Documentation
¶
Overview ¶
Package s3 stores state snapshots in an S3 bucket. The layout under the configured prefix mirrors the local store's directory layout, one object per snapshot plus a current pointer and a lock marker:
[<prefix>/]<factory>/<stack>/
current // Object holding the rev of the current snapshot.
lock // Lock marker with holder info, present while held.
snapshots/
<rev>.json.enc // rev is an RFC3339Nano timestamp.
Exclusion relies on S3 conditional writes: the lock marker and each snapshot are created with If-None-Match, so a concurrent create loses with a precondition failure instead of clobbering. Stores without conditional-write support cannot hold the lock safely and fail at Lock with the store's own error.
Index ¶
- type Store
- func (s *Store) Current() (*sdkstate.Snapshot, error)
- func (s *Store) CurrentRev() (string, error)
- func (s *Store) Delete(rev string) error
- func (s *Store) ForceUnlock() error
- func (s *Store) Get(rev string) (*sdkstate.Snapshot, error)
- func (s *Store) List() ([]string, error)
- func (s *Store) Lock(ctx context.Context) (sdkstate.Lock, error)
- func (s *Store) SetCurrent(rev string) error
- func (s *Store) Stack() string
- func (s *Store) Write(snap *sdkstate.Snapshot) (string, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Store ¶
type Store struct {
Bucket string
Prefix string
KMSKeyID string
// contains filtered or unexported fields
}
Store reads and writes snapshots under a per-stack key prefix in one bucket. KMSKeyID, when set, requests SSE-KMS with that key on every object written, the lock marker and current pointer included, so bucket policies that deny unencrypted puts hold.
func NewStore ¶
func NewStore( client *s3.Client, bucket, prefix, kmsKeyID, factory, stack string, enc sdkencrypt.Encrypter, ) (*Store, error)
NewStore returns an Store for the given factory and stack in bucket, with all objects under prefix when it is not empty. The encrypter is required, but a pass-through (encrypters.Noop) can be passed for tests.
func (*Store) Current ¶
Current returns the snapshot named by the current pointer. Returns sdkstate.ErrNoCurrent when no snapshot has been written yet.
func (*Store) CurrentRev ¶
CurrentRev returns the rev the current pointer names, or sdkstate.ErrNoCurrent.
func (*Store) Delete ¶
Delete removes the snapshot with the given rev. Removing a rev that does not exist is not an error.
func (*Store) ForceUnlock ¶
ForceUnlock removes the lock marker without checking who holds it. Operators run this to recover after a leaked lock and must ensure no concurrent run is in progress.
func (*Store) List ¶
List returns the revs of every stored snapshot in chronological order. S3 lists keys lexically, which is chronological for RFC3339Nano revs.
func (*Store) Lock ¶
Lock acquires the stack's exclusive lock by creating the lock marker with If-None-Match. Lock blocks until the create wins or ctx is canceled; while blocked it polls on the same cadence as the local store. A canceled wait names the holder in its error.
func (*Store) SetCurrent ¶
SetCurrent atomically points "current" at the named rev. The snapshot must already exist.
func (*Store) Stack ¶
Stack returns the stack name this store was constructed for. Required by the Backend interface.
func (*Store) Write ¶
Write commits snap to the bucket and returns its rev. The caller advances the current pointer with SetCurrent. Each rev starts as an RFC3339Nano timestamp; the snapshot object is created with If-None-Match, and on a precondition failure (two writes sharing the same nanosecond) a numeric suffix is appended until the create wins, so uniqueness does not depend on the clock advancing between writes.