mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-18 04:20:53 +02:00
* feat(s3/lifecycle): SeaweedS3LifecycleInternal.LifecycleDelete RPC
Adds the worker-to-S3 RPC the lifecycle worker calls to execute one
(rule, action) verdict against one entry. The S3 server is the only
component allowed to mutate filer state, so it gets the final word:
re-fetch, identity CAS, object-lock check, dispatch.
LifecycleDeleteRequest carries the routing tuple (bucket, object_path,
version_id, rule_hash, action_kind), the per-stream context echoed
into BlockerRecord on FATAL outcomes, and an EntryIdentity CAS witness
that lets the server detect mid-flight drift (mtime, size, head fid,
sorted-Extended hash).
LifecycleDeleteOutcome covers all five worker-actionable verdicts:
DONE / NOOP_RESOLVED / SKIPPED_OBJECT_LOCK / RETRY_LATER / BLOCKED.
Cursor-advance / pending-mutation rules per outcome are documented
inline.
Makefile updated to emit the gRPC stubs alongside the message types.
* feat(s3/lifecycle): LifecycleDelete server handler
Server-side handler for the worker-to-S3 RPC. Five-step flow:
1. Re-fetch live entry (NOT_FOUND -> NOOP_RESOLVED).
2. CAS on EntryIdentity (mtime / size / head fid / sorted-Extended
sha256). Mismatch -> NOOP_RESOLVED with reason STALE_IDENTITY.
3. enforceObjectLockProtections with governanceBypassAllowed=false.
Lifecycle never bypasses legal-hold or compliance retention; the
safety scan re-attempts after the hold lifts. Lock refusal ->
SKIPPED_OBJECT_LOCK (logged + counted, cursor advances).
4. Dispatch by action_kind:
- EXPIRATION_DAYS / EXPIRATION_DATE: createDeleteMarker on
versioned buckets, deleteUnversionedObjectWithClient otherwise.
- NONCURRENT_DAYS / NEWER_NONCURRENT / EXPIRED_DELETE_MARKER:
deleteSpecificObjectVersion (the marker is just a version).
- ABORT_MPU: stub returning RETRY_LATER pending Phase 5 wiring.
5. Helper failures the server can't classify as transient -> BLOCKED
with reason "FATAL_EVENT_ERROR: <detail>"; the worker writes a
durable BlockerRecord and pauses the failing stream. Filer fetch
transport errors -> RETRY_LATER (sustained transients eventually
promote to BLOCKED via the worker's retry budget).
hashExtended uses length-prefixed encoding so a forged Extended
payload (e.g. one tag value containing the byte sequence of two real
tags) can't collide with a real two-tag map. Regression test pins
this.
Tests cover identity-comparison fields, hashExtended order/delimiter
stability, empty-request rejection. Full filer-integration tests come
in Layer 2.
* fix(s3/lifecycle): use stdlib bytes.Equal for ExtendedHash compare
Replaces a hand-rolled byte slice comparator with bytes.Equal —
idiomatic, slightly faster (the stdlib version is intrinsified on
amd64/arm64), and one fewer test surface to maintain.
* refactor(s3api): trim narration from lifecycle RPC + canonicalizer
Drop step-by-step doc-block narrations on LifecycleDelete and the
helpers that reproduced what the code already says. Keep WHY one-
liners at non-obvious spots: the http.Request=nil safety claim,
why hashExtended is length-prefixed, the safety-scan revisit
contract for SKIPPED_OBJECT_LOCK, the TODO marker for ABORT_MPU.
* refactor(s3/lifecycle): retryLater helper, drop inline literals
Adds retryLater() alongside done/noopResolved/blocked so the four
LifecycleDeleteOutcome constructions look the same. Replaces the two
inline RETRY_LATER literal returns (live-fetch transport error and
the ABORT_MPU stub) with the helper. No behavior change.
* fix(s3/lifecycle): default filer-error classification to RETRY_LATER
Versioning lookup, createDeleteMarker, deleteUnversionedObjectWithClient,
and deleteSpecificObjectVersion all do filer round-trips. Most failures
are transient (filer unavailable, slow, network blip), not deterministic
per-event errors. Returning BLOCKED for them was too aggressive: BLOCKED
halts the stream until an operator intervenes, which would surface
on every transient filer hiccup.
Default these paths to RETRY_LATER. The worker's retry budget already
promotes sustained transients to BLOCKED after a configured threshold,
which is the right place for that escalation. BLOCKED stays for the
truly deterministic error: the request-shape check (missing version_id
on noncurrent delete) and the unknown-action-kind dispatch fallback.
* fix(s3/lifecycle): honor versioning Suspended on current-version expiration
Treating Suspended-versioning buckets like never-versioned ones was
wrong: per AWS S3, current-version expiration on Suspended must
remove the existing null version and insert a new delete marker (the
same behavior a user DELETE produces). The previous code branched
only on isVersioningEnabled() — which returns false for Suspended —
and dropped through to the actual-delete path, losing the version
history that Suspended buckets are still expected to keep.
Switch to getVersioningState() and dispatch on three branches:
Enabled -> createDeleteMarker (current becomes non-current)
Suspended -> deleteSpecificObjectVersion("null"), createDeleteMarker
Off / never configured -> deleteUnversionedObjectWithClient
The Suspended path's null-version deletion tolerates NotFound (the
null version may not exist when this is the first delete after a
versioning toggle); other errors classify as RETRY_LATER like the
rest of the dispatch.
* refactor(s3/lifecycle): trim narration on LifecycleDelete
Drop the 6-line versioning-state docblock and the inline
"transient -> RETRY_LATER" rationales; keep one-liners.
* fix(s3/lifecycle): bucket-not-found is NOOP; include ErrObjectNotFound
Three follow-ups from review (the rest were already addressed by
prior commits):
- Versioning lookup now distinguishes filer_pb.ErrNotFound
(BUCKET_NOT_FOUND -> NOOP_RESOLVED) from genuinely transient
failures (RETRY_LATER). A bucket deleted between live-fetch and
versioning-lookup is benign, not transient.
- deleteUnversionedObjectWithClient and deleteSpecificObjectVersion
now also recognise ErrObjectNotFound as a resolved-NOOP, matching
the live-fetch step's classification.
2210 lines
74 KiB
Go
2210 lines
74 KiB
Go
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
// versions:
|
|
// protoc-gen-go v1.36.6
|
|
// protoc v6.33.4
|
|
// source: s3_lifecycle.proto
|
|
|
|
package s3_lifecycle_pb
|
|
|
|
import (
|
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
reflect "reflect"
|
|
sync "sync"
|
|
unsafe "unsafe"
|
|
)
|
|
|
|
const (
|
|
// Verify that this generated code is sufficiently up-to-date.
|
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
)
|
|
|
|
// ActionKind classifies the lifecycle action a single compiled entry
|
|
// represents. A single XML rule may produce multiple compiled entries —
|
|
// one per populated action.
|
|
type ActionKind int32
|
|
|
|
const (
|
|
ActionKind_ACTION_KIND_UNSPECIFIED ActionKind = 0
|
|
ActionKind_EXPIRATION_DAYS ActionKind = 1 // Expiration.Days
|
|
ActionKind_EXPIRATION_DATE ActionKind = 2 // Expiration.Date
|
|
ActionKind_NONCURRENT_DAYS ActionKind = 3 // NoncurrentVersionExpiration.NoncurrentDays (with optional NewerNoncurrent retention)
|
|
ActionKind_NEWER_NONCURRENT ActionKind = 4 // NoncurrentVersionExpiration.NewerNoncurrentVersions, count-only (no NoncurrentDays)
|
|
ActionKind_ABORT_MPU ActionKind = 5 // AbortIncompleteMultipartUpload.DaysAfterInitiation
|
|
ActionKind_EXPIRED_DELETE_MARKER ActionKind = 6 // Expiration.ExpiredObjectDeleteMarker
|
|
)
|
|
|
|
// Enum value maps for ActionKind.
|
|
var (
|
|
ActionKind_name = map[int32]string{
|
|
0: "ACTION_KIND_UNSPECIFIED",
|
|
1: "EXPIRATION_DAYS",
|
|
2: "EXPIRATION_DATE",
|
|
3: "NONCURRENT_DAYS",
|
|
4: "NEWER_NONCURRENT",
|
|
5: "ABORT_MPU",
|
|
6: "EXPIRED_DELETE_MARKER",
|
|
}
|
|
ActionKind_value = map[string]int32{
|
|
"ACTION_KIND_UNSPECIFIED": 0,
|
|
"EXPIRATION_DAYS": 1,
|
|
"EXPIRATION_DATE": 2,
|
|
"NONCURRENT_DAYS": 3,
|
|
"NEWER_NONCURRENT": 4,
|
|
"ABORT_MPU": 5,
|
|
"EXPIRED_DELETE_MARKER": 6,
|
|
}
|
|
)
|
|
|
|
func (x ActionKind) Enum() *ActionKind {
|
|
p := new(ActionKind)
|
|
*p = x
|
|
return p
|
|
}
|
|
|
|
func (x ActionKind) String() string {
|
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
}
|
|
|
|
func (ActionKind) Descriptor() protoreflect.EnumDescriptor {
|
|
return file_s3_lifecycle_proto_enumTypes[0].Descriptor()
|
|
}
|
|
|
|
func (ActionKind) Type() protoreflect.EnumType {
|
|
return &file_s3_lifecycle_proto_enumTypes[0]
|
|
}
|
|
|
|
func (x ActionKind) Number() protoreflect.EnumNumber {
|
|
return protoreflect.EnumNumber(x)
|
|
}
|
|
|
|
// Deprecated: Use ActionKind.Descriptor instead.
|
|
func (ActionKind) EnumDescriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{0}
|
|
}
|
|
|
|
// LifecycleDeleteOutcome captures every per-event verdict the worker needs.
|
|
// Cursor advance / pending mutation rules:
|
|
//
|
|
// DONE -> advance cursor / drop pending
|
|
// NOOP_RESOLVED -> advance cursor / drop pending (object already gone or stale identity)
|
|
// SKIPPED_OBJECT_LOCK -> log + counter; advance cursor (per design: object lock is operator concern)
|
|
// RETRY_LATER -> hold cursor; feed retry-budget; next batch retries from same position
|
|
// BLOCKED -> hold cursor; durable BlockerRecord written; operator must intervene
|
|
type LifecycleDeleteOutcome int32
|
|
|
|
const (
|
|
LifecycleDeleteOutcome_LIFECYCLE_DELETE_OUTCOME_UNSPECIFIED LifecycleDeleteOutcome = 0
|
|
LifecycleDeleteOutcome_DONE LifecycleDeleteOutcome = 1
|
|
LifecycleDeleteOutcome_NOOP_RESOLVED LifecycleDeleteOutcome = 2
|
|
LifecycleDeleteOutcome_SKIPPED_OBJECT_LOCK LifecycleDeleteOutcome = 3
|
|
LifecycleDeleteOutcome_RETRY_LATER LifecycleDeleteOutcome = 4
|
|
LifecycleDeleteOutcome_BLOCKED LifecycleDeleteOutcome = 5
|
|
)
|
|
|
|
// Enum value maps for LifecycleDeleteOutcome.
|
|
var (
|
|
LifecycleDeleteOutcome_name = map[int32]string{
|
|
0: "LIFECYCLE_DELETE_OUTCOME_UNSPECIFIED",
|
|
1: "DONE",
|
|
2: "NOOP_RESOLVED",
|
|
3: "SKIPPED_OBJECT_LOCK",
|
|
4: "RETRY_LATER",
|
|
5: "BLOCKED",
|
|
}
|
|
LifecycleDeleteOutcome_value = map[string]int32{
|
|
"LIFECYCLE_DELETE_OUTCOME_UNSPECIFIED": 0,
|
|
"DONE": 1,
|
|
"NOOP_RESOLVED": 2,
|
|
"SKIPPED_OBJECT_LOCK": 3,
|
|
"RETRY_LATER": 4,
|
|
"BLOCKED": 5,
|
|
}
|
|
)
|
|
|
|
func (x LifecycleDeleteOutcome) Enum() *LifecycleDeleteOutcome {
|
|
p := new(LifecycleDeleteOutcome)
|
|
*p = x
|
|
return p
|
|
}
|
|
|
|
func (x LifecycleDeleteOutcome) String() string {
|
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
}
|
|
|
|
func (LifecycleDeleteOutcome) Descriptor() protoreflect.EnumDescriptor {
|
|
return file_s3_lifecycle_proto_enumTypes[1].Descriptor()
|
|
}
|
|
|
|
func (LifecycleDeleteOutcome) Type() protoreflect.EnumType {
|
|
return &file_s3_lifecycle_proto_enumTypes[1]
|
|
}
|
|
|
|
func (x LifecycleDeleteOutcome) Number() protoreflect.EnumNumber {
|
|
return protoreflect.EnumNumber(x)
|
|
}
|
|
|
|
// Deprecated: Use LifecycleDeleteOutcome.Descriptor instead.
|
|
func (LifecycleDeleteOutcome) EnumDescriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{1}
|
|
}
|
|
|
|
// StreamKind classifies the four blockable streams. ORIGINAL/PREDICATE pause
|
|
// reader cursors; BOOTSTRAP pauses a bucket walker; PENDING pauses a rule's
|
|
// drain task. Zero is an UNSPECIFIED sentinel — a BlockerRecord whose
|
|
// stream_kind reads as UNSPECIFIED is a corruption signal, not a default.
|
|
type StreamKind int32
|
|
|
|
const (
|
|
StreamKind_STREAM_KIND_UNSPECIFIED StreamKind = 0
|
|
StreamKind_ORIGINAL StreamKind = 1
|
|
StreamKind_PREDICATE StreamKind = 2
|
|
StreamKind_BOOTSTRAP StreamKind = 3
|
|
StreamKind_PENDING StreamKind = 4
|
|
)
|
|
|
|
// Enum value maps for StreamKind.
|
|
var (
|
|
StreamKind_name = map[int32]string{
|
|
0: "STREAM_KIND_UNSPECIFIED",
|
|
1: "ORIGINAL",
|
|
2: "PREDICATE",
|
|
3: "BOOTSTRAP",
|
|
4: "PENDING",
|
|
}
|
|
StreamKind_value = map[string]int32{
|
|
"STREAM_KIND_UNSPECIFIED": 0,
|
|
"ORIGINAL": 1,
|
|
"PREDICATE": 2,
|
|
"BOOTSTRAP": 3,
|
|
"PENDING": 4,
|
|
}
|
|
)
|
|
|
|
func (x StreamKind) Enum() *StreamKind {
|
|
p := new(StreamKind)
|
|
*p = x
|
|
return p
|
|
}
|
|
|
|
func (x StreamKind) String() string {
|
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
}
|
|
|
|
func (StreamKind) Descriptor() protoreflect.EnumDescriptor {
|
|
return file_s3_lifecycle_proto_enumTypes[2].Descriptor()
|
|
}
|
|
|
|
func (StreamKind) Type() protoreflect.EnumType {
|
|
return &file_s3_lifecycle_proto_enumTypes[2]
|
|
}
|
|
|
|
func (x StreamKind) Number() protoreflect.EnumNumber {
|
|
return protoreflect.EnumNumber(x)
|
|
}
|
|
|
|
// Deprecated: Use StreamKind.Descriptor instead.
|
|
func (StreamKind) EnumDescriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{2}
|
|
}
|
|
|
|
// Proto3 best practice: zero value is an UNSPECIFIED sentinel so that
|
|
// legacy / partially-populated payloads don't silently default to a
|
|
// semantically active value. Persisted state files always set explicit
|
|
// non-zero values; reading UNSPECIFIED indicates corruption or a missing
|
|
// field.
|
|
type LifecycleState_RuleMode int32
|
|
|
|
const (
|
|
LifecycleState_RULE_MODE_UNSPECIFIED LifecycleState_RuleMode = 0
|
|
LifecycleState_EVENT_DRIVEN LifecycleState_RuleMode = 1
|
|
LifecycleState_SCAN_AT_DATE LifecycleState_RuleMode = 2
|
|
LifecycleState_SCAN_ONLY LifecycleState_RuleMode = 3
|
|
LifecycleState_DISABLED LifecycleState_RuleMode = 4
|
|
LifecycleState_PENDING_BOOTSTRAP LifecycleState_RuleMode = 5
|
|
)
|
|
|
|
// Enum value maps for LifecycleState_RuleMode.
|
|
var (
|
|
LifecycleState_RuleMode_name = map[int32]string{
|
|
0: "RULE_MODE_UNSPECIFIED",
|
|
1: "EVENT_DRIVEN",
|
|
2: "SCAN_AT_DATE",
|
|
3: "SCAN_ONLY",
|
|
4: "DISABLED",
|
|
5: "PENDING_BOOTSTRAP",
|
|
}
|
|
LifecycleState_RuleMode_value = map[string]int32{
|
|
"RULE_MODE_UNSPECIFIED": 0,
|
|
"EVENT_DRIVEN": 1,
|
|
"SCAN_AT_DATE": 2,
|
|
"SCAN_ONLY": 3,
|
|
"DISABLED": 4,
|
|
"PENDING_BOOTSTRAP": 5,
|
|
}
|
|
)
|
|
|
|
func (x LifecycleState_RuleMode) Enum() *LifecycleState_RuleMode {
|
|
p := new(LifecycleState_RuleMode)
|
|
*p = x
|
|
return p
|
|
}
|
|
|
|
func (x LifecycleState_RuleMode) String() string {
|
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
}
|
|
|
|
func (LifecycleState_RuleMode) Descriptor() protoreflect.EnumDescriptor {
|
|
return file_s3_lifecycle_proto_enumTypes[3].Descriptor()
|
|
}
|
|
|
|
func (LifecycleState_RuleMode) Type() protoreflect.EnumType {
|
|
return &file_s3_lifecycle_proto_enumTypes[3]
|
|
}
|
|
|
|
func (x LifecycleState_RuleMode) Number() protoreflect.EnumNumber {
|
|
return protoreflect.EnumNumber(x)
|
|
}
|
|
|
|
// Deprecated: Use LifecycleState_RuleMode.Descriptor instead.
|
|
func (LifecycleState_RuleMode) EnumDescriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{5, 0}
|
|
}
|
|
|
|
// DEGRADED_REASON_UNSPECIFIED replaces the old NONE sentinel: an unset
|
|
// / zero degraded_reason means "no active degradation" — operators
|
|
// treat UNSPECIFIED as healthy.
|
|
type LifecycleState_DegradedReason int32
|
|
|
|
const (
|
|
LifecycleState_DEGRADED_REASON_UNSPECIFIED LifecycleState_DegradedReason = 0
|
|
LifecycleState_LAG_HIGH LifecycleState_DegradedReason = 1
|
|
LifecycleState_PENDING_FULL LifecycleState_DegradedReason = 2
|
|
LifecycleState_DELETE_FAILURES LifecycleState_DegradedReason = 3
|
|
LifecycleState_OPERATOR_PAUSED LifecycleState_DegradedReason = 4
|
|
LifecycleState_RETENTION_BELOW_HORIZON LifecycleState_DegradedReason = 5
|
|
LifecycleState_LOST_LOG LifecycleState_DegradedReason = 6
|
|
)
|
|
|
|
// Enum value maps for LifecycleState_DegradedReason.
|
|
var (
|
|
LifecycleState_DegradedReason_name = map[int32]string{
|
|
0: "DEGRADED_REASON_UNSPECIFIED",
|
|
1: "LAG_HIGH",
|
|
2: "PENDING_FULL",
|
|
3: "DELETE_FAILURES",
|
|
4: "OPERATOR_PAUSED",
|
|
5: "RETENTION_BELOW_HORIZON",
|
|
6: "LOST_LOG",
|
|
}
|
|
LifecycleState_DegradedReason_value = map[string]int32{
|
|
"DEGRADED_REASON_UNSPECIFIED": 0,
|
|
"LAG_HIGH": 1,
|
|
"PENDING_FULL": 2,
|
|
"DELETE_FAILURES": 3,
|
|
"OPERATOR_PAUSED": 4,
|
|
"RETENTION_BELOW_HORIZON": 5,
|
|
"LOST_LOG": 6,
|
|
}
|
|
)
|
|
|
|
func (x LifecycleState_DegradedReason) Enum() *LifecycleState_DegradedReason {
|
|
p := new(LifecycleState_DegradedReason)
|
|
*p = x
|
|
return p
|
|
}
|
|
|
|
func (x LifecycleState_DegradedReason) String() string {
|
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
|
}
|
|
|
|
func (LifecycleState_DegradedReason) Descriptor() protoreflect.EnumDescriptor {
|
|
return file_s3_lifecycle_proto_enumTypes[4].Descriptor()
|
|
}
|
|
|
|
func (LifecycleState_DegradedReason) Type() protoreflect.EnumType {
|
|
return &file_s3_lifecycle_proto_enumTypes[4]
|
|
}
|
|
|
|
func (x LifecycleState_DegradedReason) Number() protoreflect.EnumNumber {
|
|
return protoreflect.EnumNumber(x)
|
|
}
|
|
|
|
// Deprecated: Use LifecycleState_DegradedReason.Descriptor instead.
|
|
func (LifecycleState_DegradedReason) EnumDescriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{5, 1}
|
|
}
|
|
|
|
type LifecycleDeleteRequest struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
// Routing.
|
|
Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
|
ObjectPath string `protobuf:"bytes,2,opt,name=object_path,json=objectPath,proto3" json:"object_path,omitempty"` // bucket-relative; no leading slash
|
|
VersionId string `protobuf:"bytes,3,opt,name=version_id,json=versionId,proto3" json:"version_id,omitempty"` // empty for non-versioned
|
|
RuleHash []byte `protobuf:"bytes,4,opt,name=rule_hash,json=ruleHash,proto3" json:"rule_hash,omitempty"` // 8 bytes; matches the rule's per-rule dir
|
|
ActionKind ActionKind `protobuf:"varint,5,opt,name=action_kind,json=actionKind,proto3,enum=s3_lifecycle_pb.ActionKind" json:"action_kind,omitempty"` // chooses dispatch within the rule
|
|
// Stream context (echoed in BlockerRecord on FATAL outcomes so operators
|
|
// can resolve the right (shard, delay) tuple).
|
|
StreamShard string `protobuf:"bytes,10,opt,name=stream_shard,json=streamShard,proto3" json:"stream_shard,omitempty"`
|
|
StreamDelaySeconds int64 `protobuf:"varint,11,opt,name=stream_delay_seconds,json=streamDelaySeconds,proto3" json:"stream_delay_seconds,omitempty"`
|
|
StreamPositionTsNs int64 `protobuf:"varint,12,opt,name=stream_position_ts_ns,json=streamPositionTsNs,proto3" json:"stream_position_ts_ns,omitempty"`
|
|
StreamPositionOffset int64 `protobuf:"varint,13,opt,name=stream_position_offset,json=streamPositionOffset,proto3" json:"stream_position_offset,omitempty"`
|
|
// CAS witness. The server re-fetches the live entry and aborts as
|
|
// NOOP_RESOLVED (STALE_IDENTITY) if any field doesn't match.
|
|
ExpectedIdentity *EntryIdentity `protobuf:"bytes,20,opt,name=expected_identity,json=expectedIdentity,proto3" json:"expected_identity,omitempty"`
|
|
// Snapshot id at the time the worker computed this verdict; the server
|
|
// verifies the (rule_hash, action_kind) is still in the current policy
|
|
// snapshot and aborts as NOOP_RESOLVED (STALE_POLICY) if not.
|
|
EngineSnapshotId uint64 `protobuf:"varint,21,opt,name=engine_snapshot_id,json=engineSnapshotId,proto3" json:"engine_snapshot_id,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) Reset() {
|
|
*x = LifecycleDeleteRequest{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[0]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*LifecycleDeleteRequest) ProtoMessage() {}
|
|
|
|
func (x *LifecycleDeleteRequest) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[0]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use LifecycleDeleteRequest.ProtoReflect.Descriptor instead.
|
|
func (*LifecycleDeleteRequest) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{0}
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetBucket() string {
|
|
if x != nil {
|
|
return x.Bucket
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetObjectPath() string {
|
|
if x != nil {
|
|
return x.ObjectPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetVersionId() string {
|
|
if x != nil {
|
|
return x.VersionId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetRuleHash() []byte {
|
|
if x != nil {
|
|
return x.RuleHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetActionKind() ActionKind {
|
|
if x != nil {
|
|
return x.ActionKind
|
|
}
|
|
return ActionKind_ACTION_KIND_UNSPECIFIED
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetStreamShard() string {
|
|
if x != nil {
|
|
return x.StreamShard
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetStreamDelaySeconds() int64 {
|
|
if x != nil {
|
|
return x.StreamDelaySeconds
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetStreamPositionTsNs() int64 {
|
|
if x != nil {
|
|
return x.StreamPositionTsNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetStreamPositionOffset() int64 {
|
|
if x != nil {
|
|
return x.StreamPositionOffset
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetExpectedIdentity() *EntryIdentity {
|
|
if x != nil {
|
|
return x.ExpectedIdentity
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *LifecycleDeleteRequest) GetEngineSnapshotId() uint64 {
|
|
if x != nil {
|
|
return x.EngineSnapshotId
|
|
}
|
|
return 0
|
|
}
|
|
|
|
type LifecycleDeleteResponse struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Outcome LifecycleDeleteOutcome `protobuf:"varint,1,opt,name=outcome,proto3,enum=s3_lifecycle_pb.LifecycleDeleteOutcome" json:"outcome,omitempty"`
|
|
// Human-readable cause, e.g. "STALE_IDENTITY: mtime drift",
|
|
// "FATAL_EVENT_ERROR: malformed entry", or "TRANSPORT_ERROR: filer
|
|
// unavailable". Echoed into BlockerRecord.last_error on FATAL.
|
|
Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *LifecycleDeleteResponse) Reset() {
|
|
*x = LifecycleDeleteResponse{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[1]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *LifecycleDeleteResponse) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*LifecycleDeleteResponse) ProtoMessage() {}
|
|
|
|
func (x *LifecycleDeleteResponse) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[1]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use LifecycleDeleteResponse.ProtoReflect.Descriptor instead.
|
|
func (*LifecycleDeleteResponse) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{1}
|
|
}
|
|
|
|
func (x *LifecycleDeleteResponse) GetOutcome() LifecycleDeleteOutcome {
|
|
if x != nil {
|
|
return x.Outcome
|
|
}
|
|
return LifecycleDeleteOutcome_LIFECYCLE_DELETE_OUTCOME_UNSPECIFIED
|
|
}
|
|
|
|
func (x *LifecycleDeleteResponse) GetReason() string {
|
|
if x != nil {
|
|
return x.Reason
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// MessagePosition mirrors weed/util/log_buffer.MessagePosition for durable
|
|
// storage. ts_ns + offset uniquely identifies a position within a per-filer
|
|
// log buffer; per-shard cursors (see ReaderState) use this shape to skip past
|
|
// already-processed events when replaying.
|
|
type MessagePosition struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
TsNs int64 `protobuf:"varint,1,opt,name=ts_ns,json=tsNs,proto3" json:"ts_ns,omitempty"`
|
|
Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *MessagePosition) Reset() {
|
|
*x = MessagePosition{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[2]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *MessagePosition) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*MessagePosition) ProtoMessage() {}
|
|
|
|
func (x *MessagePosition) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[2]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use MessagePosition.ProtoReflect.Descriptor instead.
|
|
func (*MessagePosition) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{2}
|
|
}
|
|
|
|
func (x *MessagePosition) GetTsNs() int64 {
|
|
if x != nil {
|
|
return x.TsNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *MessagePosition) GetOffset() int64 {
|
|
if x != nil {
|
|
return x.Offset
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Cursor map keyed by filer_id. Each delay group's cursor (ReaderState) and
|
|
// the predicate cursor (ReaderState) are per-filer-shard maps because
|
|
// LogEntry.Offset is per-filer and not globally unique.
|
|
type FilerShardCursor struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
FilerId string `protobuf:"bytes,1,opt,name=filer_id,json=filerId,proto3" json:"filer_id,omitempty"`
|
|
Position *MessagePosition `protobuf:"bytes,2,opt,name=position,proto3" json:"position,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *FilerShardCursor) Reset() {
|
|
*x = FilerShardCursor{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[3]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *FilerShardCursor) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*FilerShardCursor) ProtoMessage() {}
|
|
|
|
func (x *FilerShardCursor) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[3]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use FilerShardCursor.ProtoReflect.Descriptor instead.
|
|
func (*FilerShardCursor) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{3}
|
|
}
|
|
|
|
func (x *FilerShardCursor) GetFilerId() string {
|
|
if x != nil {
|
|
return x.FilerId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *FilerShardCursor) GetPosition() *MessagePosition {
|
|
if x != nil {
|
|
return x.Position
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// EntryIdentity is the CAS witness used by LifecycleDelete to detect that
|
|
// the live entry hasn't changed between worker decision and server execution.
|
|
// Mismatch -> STALE_IDENTITY -> NOOP_RESOLVED.
|
|
type EntryIdentity struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
MtimeNs int64 `protobuf:"varint,1,opt,name=mtime_ns,json=mtimeNs,proto3" json:"mtime_ns,omitempty"`
|
|
Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
|
|
HeadFid string `protobuf:"bytes,3,opt,name=head_fid,json=headFid,proto3" json:"head_fid,omitempty"`
|
|
ExtendedHash []byte `protobuf:"bytes,4,opt,name=extended_hash,json=extendedHash,proto3" json:"extended_hash,omitempty"` // sha256 over sorted Extended map; cheap and stable
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *EntryIdentity) Reset() {
|
|
*x = EntryIdentity{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[4]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *EntryIdentity) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*EntryIdentity) ProtoMessage() {}
|
|
|
|
func (x *EntryIdentity) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[4]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use EntryIdentity.ProtoReflect.Descriptor instead.
|
|
func (*EntryIdentity) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{4}
|
|
}
|
|
|
|
func (x *EntryIdentity) GetMtimeNs() int64 {
|
|
if x != nil {
|
|
return x.MtimeNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *EntryIdentity) GetSize() int64 {
|
|
if x != nil {
|
|
return x.Size
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *EntryIdentity) GetHeadFid() string {
|
|
if x != nil {
|
|
return x.HeadFid
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *EntryIdentity) GetExtendedHash() []byte {
|
|
if x != nil {
|
|
return x.ExtendedHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// LifecycleState captures the durable per-action scheduling state. Keyed by
|
|
// (rule_hash, action_kind); persisted at
|
|
//
|
|
// /etc/s3/lifecycle/<bucket>/<rule_hash_hex>/<action_kind>/state
|
|
//
|
|
// A single XML <Rule> with N populated action sub-elements expands into N
|
|
// LifecycleState records, one per sibling action.
|
|
type LifecycleState struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
RuleHash []byte `protobuf:"bytes,1,opt,name=rule_hash,json=ruleHash,proto3" json:"rule_hash,omitempty"` // 8 bytes; matches the parent rule dir
|
|
ActionKind ActionKind `protobuf:"varint,2,opt,name=action_kind,json=actionKind,proto3,enum=s3_lifecycle_pb.ActionKind" json:"action_kind,omitempty"` // matches the leaf dir name
|
|
RuleId string `protobuf:"bytes,3,opt,name=rule_id,json=ruleId,proto3" json:"rule_id,omitempty"` // display only; identical across sibling actions
|
|
Mode LifecycleState_RuleMode `protobuf:"varint,4,opt,name=mode,proto3,enum=s3_lifecycle_pb.LifecycleState_RuleMode" json:"mode,omitempty"`
|
|
DegradedReason LifecycleState_DegradedReason `protobuf:"varint,5,opt,name=degraded_reason,json=degradedReason,proto3,enum=s3_lifecycle_pb.LifecycleState_DegradedReason" json:"degraded_reason,omitempty"`
|
|
DegradedSinceNs int64 `protobuf:"varint,6,opt,name=degraded_since_ns,json=degradedSinceNs,proto3" json:"degraded_since_ns,omitempty"`
|
|
BootstrapComplete bool `protobuf:"varint,7,opt,name=bootstrap_complete,json=bootstrapComplete,proto3" json:"bootstrap_complete,omitempty"`
|
|
BootstrapStartedAtNs int64 `protobuf:"varint,8,opt,name=bootstrap_started_at_ns,json=bootstrapStartedAtNs,proto3" json:"bootstrap_started_at_ns,omitempty"`
|
|
BootstrapCompletedAtNs int64 `protobuf:"varint,9,opt,name=bootstrap_completed_at_ns,json=bootstrapCompletedAtNs,proto3" json:"bootstrap_completed_at_ns,omitempty"`
|
|
// Safety-scan scheduling. Set by the safety-scan job when a SCAN_ONLY
|
|
// (or periodic safety-scan) bootstrap pass completes; consulted by the
|
|
// detector to decide whether to emit the next bootstrap task.
|
|
LastSafetyScanTsNs int64 `protobuf:"varint,10,opt,name=last_safety_scan_ts_ns,json=lastSafetyScanTsNs,proto3" json:"last_safety_scan_ts_ns,omitempty"`
|
|
NextSafetyScanTsNs int64 `protobuf:"varint,11,opt,name=next_safety_scan_ts_ns,json=nextSafetyScanTsNs,proto3" json:"next_safety_scan_ts_ns,omitempty"`
|
|
// Counters for observability; no behavior depends on these.
|
|
// - evaluated_total: live entries the worker considered for this action
|
|
// (filter-matched + due-checked); includes objects that ended up not
|
|
// yet eligible.
|
|
// - expired_total: successful DONE outcomes (object/version/marker/MPU
|
|
// removed) under this action.
|
|
// - metadata_only_total: subset of expired_total where the worker
|
|
// short-circuited via volume-TTL routing (chunks left to volume GC).
|
|
// - error_total: outcomes that did NOT advance the cursor under this
|
|
// action (RETRY_LATER, BLOCKED, FATAL_EVENT_ERROR).
|
|
EvaluatedTotal int64 `protobuf:"varint,12,opt,name=evaluated_total,json=evaluatedTotal,proto3" json:"evaluated_total,omitempty"`
|
|
ExpiredTotal int64 `protobuf:"varint,13,opt,name=expired_total,json=expiredTotal,proto3" json:"expired_total,omitempty"`
|
|
MetadataOnlyTotal int64 `protobuf:"varint,14,opt,name=metadata_only_total,json=metadataOnlyTotal,proto3" json:"metadata_only_total,omitempty"`
|
|
ErrorTotal int64 `protobuf:"varint,15,opt,name=error_total,json=errorTotal,proto3" json:"error_total,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *LifecycleState) Reset() {
|
|
*x = LifecycleState{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[5]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *LifecycleState) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*LifecycleState) ProtoMessage() {}
|
|
|
|
func (x *LifecycleState) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[5]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use LifecycleState.ProtoReflect.Descriptor instead.
|
|
func (*LifecycleState) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{5}
|
|
}
|
|
|
|
func (x *LifecycleState) GetRuleHash() []byte {
|
|
if x != nil {
|
|
return x.RuleHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *LifecycleState) GetActionKind() ActionKind {
|
|
if x != nil {
|
|
return x.ActionKind
|
|
}
|
|
return ActionKind_ACTION_KIND_UNSPECIFIED
|
|
}
|
|
|
|
func (x *LifecycleState) GetRuleId() string {
|
|
if x != nil {
|
|
return x.RuleId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *LifecycleState) GetMode() LifecycleState_RuleMode {
|
|
if x != nil {
|
|
return x.Mode
|
|
}
|
|
return LifecycleState_RULE_MODE_UNSPECIFIED
|
|
}
|
|
|
|
func (x *LifecycleState) GetDegradedReason() LifecycleState_DegradedReason {
|
|
if x != nil {
|
|
return x.DegradedReason
|
|
}
|
|
return LifecycleState_DEGRADED_REASON_UNSPECIFIED
|
|
}
|
|
|
|
func (x *LifecycleState) GetDegradedSinceNs() int64 {
|
|
if x != nil {
|
|
return x.DegradedSinceNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetBootstrapComplete() bool {
|
|
if x != nil {
|
|
return x.BootstrapComplete
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (x *LifecycleState) GetBootstrapStartedAtNs() int64 {
|
|
if x != nil {
|
|
return x.BootstrapStartedAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetBootstrapCompletedAtNs() int64 {
|
|
if x != nil {
|
|
return x.BootstrapCompletedAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetLastSafetyScanTsNs() int64 {
|
|
if x != nil {
|
|
return x.LastSafetyScanTsNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetNextSafetyScanTsNs() int64 {
|
|
if x != nil {
|
|
return x.NextSafetyScanTsNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetEvaluatedTotal() int64 {
|
|
if x != nil {
|
|
return x.EvaluatedTotal
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetExpiredTotal() int64 {
|
|
if x != nil {
|
|
return x.ExpiredTotal
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetMetadataOnlyTotal() int64 {
|
|
if x != nil {
|
|
return x.MetadataOnlyTotal
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *LifecycleState) GetErrorTotal() int64 {
|
|
if x != nil {
|
|
return x.ErrorTotal
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// PendingItem records a not-yet-due eligibility for late-predicate exceptions
|
|
// (e.g. tag added at age 30d on a 60d rule). Drained by s3.lifecycle.drain.
|
|
// One use only — not the steady-state path.
|
|
type PendingItem struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
ObjectPath string `protobuf:"bytes,1,opt,name=object_path,json=objectPath,proto3" json:"object_path,omitempty"`
|
|
VersionId string `protobuf:"bytes,2,opt,name=version_id,json=versionId,proto3" json:"version_id,omitempty"`
|
|
DueAtNs int64 `protobuf:"varint,3,opt,name=due_at_ns,json=dueAtNs,proto3" json:"due_at_ns,omitempty"`
|
|
ExpectedIdentity *EntryIdentity `protobuf:"bytes,4,opt,name=expected_identity,json=expectedIdentity,proto3" json:"expected_identity,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *PendingItem) Reset() {
|
|
*x = PendingItem{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[6]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *PendingItem) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*PendingItem) ProtoMessage() {}
|
|
|
|
func (x *PendingItem) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[6]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use PendingItem.ProtoReflect.Descriptor instead.
|
|
func (*PendingItem) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{6}
|
|
}
|
|
|
|
func (x *PendingItem) GetObjectPath() string {
|
|
if x != nil {
|
|
return x.ObjectPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *PendingItem) GetVersionId() string {
|
|
if x != nil {
|
|
return x.VersionId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *PendingItem) GetDueAtNs() int64 {
|
|
if x != nil {
|
|
return x.DueAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *PendingItem) GetExpectedIdentity() *EntryIdentity {
|
|
if x != nil {
|
|
return x.ExpectedIdentity
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BootstrapState tracks the bucket walker's resume point. Operator-resolution
|
|
// of a BOOTSTRAP-stream blocker does NOT mutate this field — the next
|
|
// scheduled bootstrap task picks up from last_scanned_path and re-walks.
|
|
type BootstrapState struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
LastScannedPath string `protobuf:"bytes,1,opt,name=last_scanned_path,json=lastScannedPath,proto3" json:"last_scanned_path,omitempty"`
|
|
StartedAtNs int64 `protobuf:"varint,2,opt,name=started_at_ns,json=startedAtNs,proto3" json:"started_at_ns,omitempty"`
|
|
CompletedAtNs int64 `protobuf:"varint,3,opt,name=completed_at_ns,json=completedAtNs,proto3" json:"completed_at_ns,omitempty"` // zero while in progress
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *BootstrapState) Reset() {
|
|
*x = BootstrapState{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[7]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *BootstrapState) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*BootstrapState) ProtoMessage() {}
|
|
|
|
func (x *BootstrapState) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[7]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use BootstrapState.ProtoReflect.Descriptor instead.
|
|
func (*BootstrapState) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{7}
|
|
}
|
|
|
|
func (x *BootstrapState) GetLastScannedPath() string {
|
|
if x != nil {
|
|
return x.LastScannedPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BootstrapState) GetStartedAtNs() int64 {
|
|
if x != nil {
|
|
return x.StartedAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *BootstrapState) GetCompletedAtNs() int64 {
|
|
if x != nil {
|
|
return x.CompletedAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// ReaderState is the cluster-singleton reader's durable cursors. One file at
|
|
// /etc/s3/lifecycle/_reader/reader_state, written by the singleton task.
|
|
type ReaderState struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
PrimaryFilerEndpoint string `protobuf:"bytes,1,opt,name=primary_filer_endpoint,json=primaryFilerEndpoint,proto3" json:"primary_filer_endpoint,omitempty"`
|
|
// Per-delay-group, per-filer-shard cursors. Outer key is delay_seconds.
|
|
// Inner FilerShardCursor list maps filer_id -> MessagePosition.
|
|
LastProcessedOriginal map[int64]*FilerShardCursorList `protobuf:"bytes,2,rep,name=last_processed_original,json=lastProcessedOriginal,proto3" json:"last_processed_original,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
|
// Predicate-change pass cursor, keyed by filer_id.
|
|
LastProcessedPredicate []*FilerShardCursor `protobuf:"bytes,3,rep,name=last_processed_predicate,json=lastProcessedPredicate,proto3" json:"last_processed_predicate,omitempty"`
|
|
// Filer-shard keys whose cursor reached range.latest and were safely GC'd.
|
|
// Used by the lost-log gate at task entry to distinguish "F was tail-drained
|
|
// safely then pruned" from "F's logs vanished before catch-up". Encoded as
|
|
// stream-specific keys (same shape as RetryBudgetEntry.StreamKey).
|
|
TailDrainedStreams []*TailDrainedKey `protobuf:"bytes,4,rep,name=tail_drained_streams,json=tailDrainedStreams,proto3" json:"tail_drained_streams,omitempty"`
|
|
LastCheckpointNs int64 `protobuf:"varint,5,opt,name=last_checkpoint_ns,json=lastCheckpointNs,proto3" json:"last_checkpoint_ns,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *ReaderState) Reset() {
|
|
*x = ReaderState{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[8]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *ReaderState) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*ReaderState) ProtoMessage() {}
|
|
|
|
func (x *ReaderState) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[8]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use ReaderState.ProtoReflect.Descriptor instead.
|
|
func (*ReaderState) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{8}
|
|
}
|
|
|
|
func (x *ReaderState) GetPrimaryFilerEndpoint() string {
|
|
if x != nil {
|
|
return x.PrimaryFilerEndpoint
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *ReaderState) GetLastProcessedOriginal() map[int64]*FilerShardCursorList {
|
|
if x != nil {
|
|
return x.LastProcessedOriginal
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *ReaderState) GetLastProcessedPredicate() []*FilerShardCursor {
|
|
if x != nil {
|
|
return x.LastProcessedPredicate
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *ReaderState) GetTailDrainedStreams() []*TailDrainedKey {
|
|
if x != nil {
|
|
return x.TailDrainedStreams
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *ReaderState) GetLastCheckpointNs() int64 {
|
|
if x != nil {
|
|
return x.LastCheckpointNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
type FilerShardCursorList struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Cursors []*FilerShardCursor `protobuf:"bytes,1,rep,name=cursors,proto3" json:"cursors,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *FilerShardCursorList) Reset() {
|
|
*x = FilerShardCursorList{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[9]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *FilerShardCursorList) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*FilerShardCursorList) ProtoMessage() {}
|
|
|
|
func (x *FilerShardCursorList) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[9]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use FilerShardCursorList.ProtoReflect.Descriptor instead.
|
|
func (*FilerShardCursorList) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{9}
|
|
}
|
|
|
|
func (x *FilerShardCursorList) GetCursors() []*FilerShardCursor {
|
|
if x != nil {
|
|
return x.Cursors
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TailDrainedKey identifies a (stream_kind, shard, [delay]) tuple whose
|
|
// cursor previously caught up to range.latest. Persisted in ReaderState so
|
|
// the lost-log gate can distinguish safe drain from data loss.
|
|
type TailDrainedKey struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
StreamKind StreamKind `protobuf:"varint,1,opt,name=stream_kind,json=streamKind,proto3,enum=s3_lifecycle_pb.StreamKind" json:"stream_kind,omitempty"`
|
|
FilerId string `protobuf:"bytes,2,opt,name=filer_id,json=filerId,proto3" json:"filer_id,omitempty"`
|
|
DelaySeconds int64 `protobuf:"varint,3,opt,name=delay_seconds,json=delaySeconds,proto3" json:"delay_seconds,omitempty"` // populated when stream_kind == ORIGINAL
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *TailDrainedKey) Reset() {
|
|
*x = TailDrainedKey{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[10]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *TailDrainedKey) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*TailDrainedKey) ProtoMessage() {}
|
|
|
|
func (x *TailDrainedKey) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[10]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use TailDrainedKey.ProtoReflect.Descriptor instead.
|
|
func (*TailDrainedKey) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{10}
|
|
}
|
|
|
|
func (x *TailDrainedKey) GetStreamKind() StreamKind {
|
|
if x != nil {
|
|
return x.StreamKind
|
|
}
|
|
return StreamKind_STREAM_KIND_UNSPECIFIED
|
|
}
|
|
|
|
func (x *TailDrainedKey) GetFilerId() string {
|
|
if x != nil {
|
|
return x.FilerId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *TailDrainedKey) GetDelaySeconds() int64 {
|
|
if x != nil {
|
|
return x.DelaySeconds
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// BlockerRecord is the durable record of a paused stream. The cursor stays
|
|
// at the failing position until the operator clears it via
|
|
// `s3.lifecycle.blockers retry|resume|quarantine`. There is no automatic
|
|
// dead-letter — silently routing a failed delete decision aside is unsafe
|
|
// for lifecycle.
|
|
type BlockerRecord struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
StreamKind StreamKind `protobuf:"varint,1,opt,name=stream_kind,json=streamKind,proto3,enum=s3_lifecycle_pb.StreamKind" json:"stream_kind,omitempty"`
|
|
// Stream-specific scoping; populated per stream_kind.
|
|
Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` // filer_id; ORIGINAL/PREDICATE only
|
|
DelaySeconds int64 `protobuf:"varint,3,opt,name=delay_seconds,json=delaySeconds,proto3" json:"delay_seconds,omitempty"` // ORIGINAL only
|
|
Position *MessagePosition `protobuf:"bytes,4,opt,name=position,proto3" json:"position,omitempty"` // ORIGINAL/PREDICATE only
|
|
// Common context. bucket/object_path/version_id always populated.
|
|
// rule_hash and action_kind are OPTIONAL: empty / UNSPECIFIED for
|
|
// pre-evaluation failures (e.g. handleEvent fetchLive FATAL where no
|
|
// action has been evaluated). When populated, both are set together —
|
|
// the failure is bound to a specific (rule, action) pair.
|
|
RuleHash []byte `protobuf:"bytes,5,opt,name=rule_hash,json=ruleHash,proto3" json:"rule_hash,omitempty"`
|
|
Bucket string `protobuf:"bytes,6,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
|
ObjectPath string `protobuf:"bytes,7,opt,name=object_path,json=objectPath,proto3" json:"object_path,omitempty"`
|
|
VersionId string `protobuf:"bytes,8,opt,name=version_id,json=versionId,proto3" json:"version_id,omitempty"`
|
|
ActionKind ActionKind `protobuf:"varint,14,opt,name=action_kind,json=actionKind,proto3,enum=s3_lifecycle_pb.ActionKind" json:"action_kind,omitempty"` // optional; UNSPECIFIED for pre-evaluation failures
|
|
Reason string `protobuf:"bytes,9,opt,name=reason,proto3" json:"reason,omitempty"` // "FATAL_EVENT_ERROR: malformed entry"
|
|
LastError string `protobuf:"bytes,10,opt,name=last_error,json=lastError,proto3" json:"last_error,omitempty"` // raw error string from the last attempt
|
|
FirstSeenAtNs int64 `protobuf:"varint,11,opt,name=first_seen_at_ns,json=firstSeenAtNs,proto3" json:"first_seen_at_ns,omitempty"`
|
|
LastRetryAtNs int64 `protobuf:"varint,12,opt,name=last_retry_at_ns,json=lastRetryAtNs,proto3" json:"last_retry_at_ns,omitempty"`
|
|
RetryCount int32 `protobuf:"varint,13,opt,name=retry_count,json=retryCount,proto3" json:"retry_count,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *BlockerRecord) Reset() {
|
|
*x = BlockerRecord{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[11]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *BlockerRecord) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*BlockerRecord) ProtoMessage() {}
|
|
|
|
func (x *BlockerRecord) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[11]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use BlockerRecord.ProtoReflect.Descriptor instead.
|
|
func (*BlockerRecord) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{11}
|
|
}
|
|
|
|
func (x *BlockerRecord) GetStreamKind() StreamKind {
|
|
if x != nil {
|
|
return x.StreamKind
|
|
}
|
|
return StreamKind_STREAM_KIND_UNSPECIFIED
|
|
}
|
|
|
|
func (x *BlockerRecord) GetShard() string {
|
|
if x != nil {
|
|
return x.Shard
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BlockerRecord) GetDelaySeconds() int64 {
|
|
if x != nil {
|
|
return x.DelaySeconds
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *BlockerRecord) GetPosition() *MessagePosition {
|
|
if x != nil {
|
|
return x.Position
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *BlockerRecord) GetRuleHash() []byte {
|
|
if x != nil {
|
|
return x.RuleHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *BlockerRecord) GetBucket() string {
|
|
if x != nil {
|
|
return x.Bucket
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BlockerRecord) GetObjectPath() string {
|
|
if x != nil {
|
|
return x.ObjectPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BlockerRecord) GetVersionId() string {
|
|
if x != nil {
|
|
return x.VersionId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BlockerRecord) GetActionKind() ActionKind {
|
|
if x != nil {
|
|
return x.ActionKind
|
|
}
|
|
return ActionKind_ACTION_KIND_UNSPECIFIED
|
|
}
|
|
|
|
func (x *BlockerRecord) GetReason() string {
|
|
if x != nil {
|
|
return x.Reason
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BlockerRecord) GetLastError() string {
|
|
if x != nil {
|
|
return x.LastError
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BlockerRecord) GetFirstSeenAtNs() int64 {
|
|
if x != nil {
|
|
return x.FirstSeenAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *BlockerRecord) GetLastRetryAtNs() int64 {
|
|
if x != nil {
|
|
return x.LastRetryAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *BlockerRecord) GetRetryCount() int32 {
|
|
if x != nil {
|
|
return x.RetryCount
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// StreamKey is the shape used by retry-budget tracking. One of four shapes
|
|
// per stream_kind, since the identifying tuple differs.
|
|
type StreamKey struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
// Types that are valid to be assigned to Key:
|
|
//
|
|
// *StreamKey_Original
|
|
// *StreamKey_Predicate
|
|
// *StreamKey_Bootstrap
|
|
// *StreamKey_Pending
|
|
Key isStreamKey_Key `protobuf_oneof:"key"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *StreamKey) Reset() {
|
|
*x = StreamKey{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[12]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *StreamKey) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*StreamKey) ProtoMessage() {}
|
|
|
|
func (x *StreamKey) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[12]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use StreamKey.ProtoReflect.Descriptor instead.
|
|
func (*StreamKey) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{12}
|
|
}
|
|
|
|
func (x *StreamKey) GetKey() isStreamKey_Key {
|
|
if x != nil {
|
|
return x.Key
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *StreamKey) GetOriginal() *OriginalKey {
|
|
if x != nil {
|
|
if x, ok := x.Key.(*StreamKey_Original); ok {
|
|
return x.Original
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *StreamKey) GetPredicate() *PredicateKey {
|
|
if x != nil {
|
|
if x, ok := x.Key.(*StreamKey_Predicate); ok {
|
|
return x.Predicate
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *StreamKey) GetBootstrap() *BootstrapKey {
|
|
if x != nil {
|
|
if x, ok := x.Key.(*StreamKey_Bootstrap); ok {
|
|
return x.Bootstrap
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *StreamKey) GetPending() *PendingKey {
|
|
if x != nil {
|
|
if x, ok := x.Key.(*StreamKey_Pending); ok {
|
|
return x.Pending
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type isStreamKey_Key interface {
|
|
isStreamKey_Key()
|
|
}
|
|
|
|
type StreamKey_Original struct {
|
|
Original *OriginalKey `protobuf:"bytes,1,opt,name=original,proto3,oneof"`
|
|
}
|
|
|
|
type StreamKey_Predicate struct {
|
|
Predicate *PredicateKey `protobuf:"bytes,2,opt,name=predicate,proto3,oneof"`
|
|
}
|
|
|
|
type StreamKey_Bootstrap struct {
|
|
Bootstrap *BootstrapKey `protobuf:"bytes,3,opt,name=bootstrap,proto3,oneof"`
|
|
}
|
|
|
|
type StreamKey_Pending struct {
|
|
Pending *PendingKey `protobuf:"bytes,4,opt,name=pending,proto3,oneof"`
|
|
}
|
|
|
|
func (*StreamKey_Original) isStreamKey_Key() {}
|
|
|
|
func (*StreamKey_Predicate) isStreamKey_Key() {}
|
|
|
|
func (*StreamKey_Bootstrap) isStreamKey_Key() {}
|
|
|
|
func (*StreamKey_Pending) isStreamKey_Key() {}
|
|
|
|
type OriginalKey struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Shard string `protobuf:"bytes,1,opt,name=shard,proto3" json:"shard,omitempty"`
|
|
DelaySeconds int64 `protobuf:"varint,2,opt,name=delay_seconds,json=delaySeconds,proto3" json:"delay_seconds,omitempty"`
|
|
Position *MessagePosition `protobuf:"bytes,3,opt,name=position,proto3" json:"position,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *OriginalKey) Reset() {
|
|
*x = OriginalKey{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[13]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *OriginalKey) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*OriginalKey) ProtoMessage() {}
|
|
|
|
func (x *OriginalKey) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[13]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use OriginalKey.ProtoReflect.Descriptor instead.
|
|
func (*OriginalKey) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{13}
|
|
}
|
|
|
|
func (x *OriginalKey) GetShard() string {
|
|
if x != nil {
|
|
return x.Shard
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *OriginalKey) GetDelaySeconds() int64 {
|
|
if x != nil {
|
|
return x.DelaySeconds
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *OriginalKey) GetPosition() *MessagePosition {
|
|
if x != nil {
|
|
return x.Position
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type PredicateKey struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Shard string `protobuf:"bytes,1,opt,name=shard,proto3" json:"shard,omitempty"`
|
|
Position *MessagePosition `protobuf:"bytes,2,opt,name=position,proto3" json:"position,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *PredicateKey) Reset() {
|
|
*x = PredicateKey{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[14]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *PredicateKey) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*PredicateKey) ProtoMessage() {}
|
|
|
|
func (x *PredicateKey) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[14]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use PredicateKey.ProtoReflect.Descriptor instead.
|
|
func (*PredicateKey) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{14}
|
|
}
|
|
|
|
func (x *PredicateKey) GetShard() string {
|
|
if x != nil {
|
|
return x.Shard
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *PredicateKey) GetPosition() *MessagePosition {
|
|
if x != nil {
|
|
return x.Position
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type BootstrapKey struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
|
ObjectPath string `protobuf:"bytes,2,opt,name=object_path,json=objectPath,proto3" json:"object_path,omitempty"`
|
|
VersionId string `protobuf:"bytes,3,opt,name=version_id,json=versionId,proto3" json:"version_id,omitempty"`
|
|
RuleHash []byte `protobuf:"bytes,4,opt,name=rule_hash,json=ruleHash,proto3" json:"rule_hash,omitempty"`
|
|
ActionKind ActionKind `protobuf:"varint,5,opt,name=action_kind,json=actionKind,proto3,enum=s3_lifecycle_pb.ActionKind" json:"action_kind,omitempty"` // distinguishes per-action streams under one rule
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *BootstrapKey) Reset() {
|
|
*x = BootstrapKey{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[15]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *BootstrapKey) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*BootstrapKey) ProtoMessage() {}
|
|
|
|
func (x *BootstrapKey) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[15]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use BootstrapKey.ProtoReflect.Descriptor instead.
|
|
func (*BootstrapKey) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{15}
|
|
}
|
|
|
|
func (x *BootstrapKey) GetBucket() string {
|
|
if x != nil {
|
|
return x.Bucket
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BootstrapKey) GetObjectPath() string {
|
|
if x != nil {
|
|
return x.ObjectPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BootstrapKey) GetVersionId() string {
|
|
if x != nil {
|
|
return x.VersionId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *BootstrapKey) GetRuleHash() []byte {
|
|
if x != nil {
|
|
return x.RuleHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *BootstrapKey) GetActionKind() ActionKind {
|
|
if x != nil {
|
|
return x.ActionKind
|
|
}
|
|
return ActionKind_ACTION_KIND_UNSPECIFIED
|
|
}
|
|
|
|
type PendingKey struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
|
RuleHash []byte `protobuf:"bytes,2,opt,name=rule_hash,json=ruleHash,proto3" json:"rule_hash,omitempty"`
|
|
ObjectPath string `protobuf:"bytes,3,opt,name=object_path,json=objectPath,proto3" json:"object_path,omitempty"`
|
|
VersionId string `protobuf:"bytes,4,opt,name=version_id,json=versionId,proto3" json:"version_id,omitempty"`
|
|
ActionKind ActionKind `protobuf:"varint,5,opt,name=action_kind,json=actionKind,proto3,enum=s3_lifecycle_pb.ActionKind" json:"action_kind,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *PendingKey) Reset() {
|
|
*x = PendingKey{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[16]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *PendingKey) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*PendingKey) ProtoMessage() {}
|
|
|
|
func (x *PendingKey) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[16]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use PendingKey.ProtoReflect.Descriptor instead.
|
|
func (*PendingKey) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{16}
|
|
}
|
|
|
|
func (x *PendingKey) GetBucket() string {
|
|
if x != nil {
|
|
return x.Bucket
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *PendingKey) GetRuleHash() []byte {
|
|
if x != nil {
|
|
return x.RuleHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *PendingKey) GetObjectPath() string {
|
|
if x != nil {
|
|
return x.ObjectPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *PendingKey) GetVersionId() string {
|
|
if x != nil {
|
|
return x.VersionId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *PendingKey) GetActionKind() ActionKind {
|
|
if x != nil {
|
|
return x.ActionKind
|
|
}
|
|
return ActionKind_ACTION_KIND_UNSPECIFIED
|
|
}
|
|
|
|
// RetryBudgetEntry tracks consecutive RETRY_LATER outcomes for a stream key.
|
|
// Promotes to BLOCKED when consecutive_retries >= retryBudgetMax (30) or age
|
|
// >= retryBudgetMaxAge (4h). Compacts on success (clearRetryBudget).
|
|
type RetryBudgetEntry struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Key *StreamKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
|
ConsecutiveRetries int32 `protobuf:"varint,2,opt,name=consecutive_retries,json=consecutiveRetries,proto3" json:"consecutive_retries,omitempty"`
|
|
FirstSeenAtNs int64 `protobuf:"varint,3,opt,name=first_seen_at_ns,json=firstSeenAtNs,proto3" json:"first_seen_at_ns,omitempty"`
|
|
LastRetryAtNs int64 `protobuf:"varint,4,opt,name=last_retry_at_ns,json=lastRetryAtNs,proto3" json:"last_retry_at_ns,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *RetryBudgetEntry) Reset() {
|
|
*x = RetryBudgetEntry{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[17]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *RetryBudgetEntry) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*RetryBudgetEntry) ProtoMessage() {}
|
|
|
|
func (x *RetryBudgetEntry) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[17]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use RetryBudgetEntry.ProtoReflect.Descriptor instead.
|
|
func (*RetryBudgetEntry) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{17}
|
|
}
|
|
|
|
func (x *RetryBudgetEntry) GetKey() *StreamKey {
|
|
if x != nil {
|
|
return x.Key
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *RetryBudgetEntry) GetConsecutiveRetries() int32 {
|
|
if x != nil {
|
|
return x.ConsecutiveRetries
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *RetryBudgetEntry) GetFirstSeenAtNs() int64 {
|
|
if x != nil {
|
|
return x.FirstSeenAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (x *RetryBudgetEntry) GetLastRetryAtNs() int64 {
|
|
if x != nil {
|
|
return x.LastRetryAtNs
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// RetryTarget carries routing info needed to (a) write a BlockerRecord on
|
|
// promotion and (b) re-invoke the right primitive on operator retry. We
|
|
// deliberately do NOT carry expected_identity or action: the handler
|
|
// re-fetches live state and re-evaluates from scratch.
|
|
type RetryTarget struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Key *StreamKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
|
Bucket string `protobuf:"bytes,2,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
|
ObjectPath string `protobuf:"bytes,3,opt,name=object_path,json=objectPath,proto3" json:"object_path,omitempty"`
|
|
VersionId string `protobuf:"bytes,4,opt,name=version_id,json=versionId,proto3" json:"version_id,omitempty"`
|
|
RuleHash []byte `protobuf:"bytes,5,opt,name=rule_hash,json=ruleHash,proto3" json:"rule_hash,omitempty"`
|
|
ActionKind ActionKind `protobuf:"varint,6,opt,name=action_kind,json=actionKind,proto3,enum=s3_lifecycle_pb.ActionKind" json:"action_kind,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *RetryTarget) Reset() {
|
|
*x = RetryTarget{}
|
|
mi := &file_s3_lifecycle_proto_msgTypes[18]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *RetryTarget) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*RetryTarget) ProtoMessage() {}
|
|
|
|
func (x *RetryTarget) ProtoReflect() protoreflect.Message {
|
|
mi := &file_s3_lifecycle_proto_msgTypes[18]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use RetryTarget.ProtoReflect.Descriptor instead.
|
|
func (*RetryTarget) Descriptor() ([]byte, []int) {
|
|
return file_s3_lifecycle_proto_rawDescGZIP(), []int{18}
|
|
}
|
|
|
|
func (x *RetryTarget) GetKey() *StreamKey {
|
|
if x != nil {
|
|
return x.Key
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *RetryTarget) GetBucket() string {
|
|
if x != nil {
|
|
return x.Bucket
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *RetryTarget) GetObjectPath() string {
|
|
if x != nil {
|
|
return x.ObjectPath
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *RetryTarget) GetVersionId() string {
|
|
if x != nil {
|
|
return x.VersionId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *RetryTarget) GetRuleHash() []byte {
|
|
if x != nil {
|
|
return x.RuleHash
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *RetryTarget) GetActionKind() ActionKind {
|
|
if x != nil {
|
|
return x.ActionKind
|
|
}
|
|
return ActionKind_ACTION_KIND_UNSPECIFIED
|
|
}
|
|
|
|
var File_s3_lifecycle_proto protoreflect.FileDescriptor
|
|
|
|
const file_s3_lifecycle_proto_rawDesc = "" +
|
|
"\n" +
|
|
"\x12s3_lifecycle.proto\x12\x0fs3_lifecycle_pb\"\x84\x04\n" +
|
|
"\x16LifecycleDeleteRequest\x12\x16\n" +
|
|
"\x06bucket\x18\x01 \x01(\tR\x06bucket\x12\x1f\n" +
|
|
"\vobject_path\x18\x02 \x01(\tR\n" +
|
|
"objectPath\x12\x1d\n" +
|
|
"\n" +
|
|
"version_id\x18\x03 \x01(\tR\tversionId\x12\x1b\n" +
|
|
"\trule_hash\x18\x04 \x01(\fR\bruleHash\x12<\n" +
|
|
"\vaction_kind\x18\x05 \x01(\x0e2\x1b.s3_lifecycle_pb.ActionKindR\n" +
|
|
"actionKind\x12!\n" +
|
|
"\fstream_shard\x18\n" +
|
|
" \x01(\tR\vstreamShard\x120\n" +
|
|
"\x14stream_delay_seconds\x18\v \x01(\x03R\x12streamDelaySeconds\x121\n" +
|
|
"\x15stream_position_ts_ns\x18\f \x01(\x03R\x12streamPositionTsNs\x124\n" +
|
|
"\x16stream_position_offset\x18\r \x01(\x03R\x14streamPositionOffset\x12K\n" +
|
|
"\x11expected_identity\x18\x14 \x01(\v2\x1e.s3_lifecycle_pb.EntryIdentityR\x10expectedIdentity\x12,\n" +
|
|
"\x12engine_snapshot_id\x18\x15 \x01(\x04R\x10engineSnapshotId\"t\n" +
|
|
"\x17LifecycleDeleteResponse\x12A\n" +
|
|
"\aoutcome\x18\x01 \x01(\x0e2'.s3_lifecycle_pb.LifecycleDeleteOutcomeR\aoutcome\x12\x16\n" +
|
|
"\x06reason\x18\x02 \x01(\tR\x06reason\">\n" +
|
|
"\x0fMessagePosition\x12\x13\n" +
|
|
"\x05ts_ns\x18\x01 \x01(\x03R\x04tsNs\x12\x16\n" +
|
|
"\x06offset\x18\x02 \x01(\x03R\x06offset\"k\n" +
|
|
"\x10FilerShardCursor\x12\x19\n" +
|
|
"\bfiler_id\x18\x01 \x01(\tR\afilerId\x12<\n" +
|
|
"\bposition\x18\x02 \x01(\v2 .s3_lifecycle_pb.MessagePositionR\bposition\"~\n" +
|
|
"\rEntryIdentity\x12\x19\n" +
|
|
"\bmtime_ns\x18\x01 \x01(\x03R\amtimeNs\x12\x12\n" +
|
|
"\x04size\x18\x02 \x01(\x03R\x04size\x12\x19\n" +
|
|
"\bhead_fid\x18\x03 \x01(\tR\aheadFid\x12#\n" +
|
|
"\rextended_hash\x18\x04 \x01(\fR\fextendedHash\"\x97\b\n" +
|
|
"\x0eLifecycleState\x12\x1b\n" +
|
|
"\trule_hash\x18\x01 \x01(\fR\bruleHash\x12<\n" +
|
|
"\vaction_kind\x18\x02 \x01(\x0e2\x1b.s3_lifecycle_pb.ActionKindR\n" +
|
|
"actionKind\x12\x17\n" +
|
|
"\arule_id\x18\x03 \x01(\tR\x06ruleId\x12<\n" +
|
|
"\x04mode\x18\x04 \x01(\x0e2(.s3_lifecycle_pb.LifecycleState.RuleModeR\x04mode\x12W\n" +
|
|
"\x0fdegraded_reason\x18\x05 \x01(\x0e2..s3_lifecycle_pb.LifecycleState.DegradedReasonR\x0edegradedReason\x12*\n" +
|
|
"\x11degraded_since_ns\x18\x06 \x01(\x03R\x0fdegradedSinceNs\x12-\n" +
|
|
"\x12bootstrap_complete\x18\a \x01(\bR\x11bootstrapComplete\x125\n" +
|
|
"\x17bootstrap_started_at_ns\x18\b \x01(\x03R\x14bootstrapStartedAtNs\x129\n" +
|
|
"\x19bootstrap_completed_at_ns\x18\t \x01(\x03R\x16bootstrapCompletedAtNs\x122\n" +
|
|
"\x16last_safety_scan_ts_ns\x18\n" +
|
|
" \x01(\x03R\x12lastSafetyScanTsNs\x122\n" +
|
|
"\x16next_safety_scan_ts_ns\x18\v \x01(\x03R\x12nextSafetyScanTsNs\x12'\n" +
|
|
"\x0fevaluated_total\x18\f \x01(\x03R\x0eevaluatedTotal\x12#\n" +
|
|
"\rexpired_total\x18\r \x01(\x03R\fexpiredTotal\x12.\n" +
|
|
"\x13metadata_only_total\x18\x0e \x01(\x03R\x11metadataOnlyTotal\x12\x1f\n" +
|
|
"\verror_total\x18\x0f \x01(\x03R\n" +
|
|
"errorTotal\"}\n" +
|
|
"\bRuleMode\x12\x19\n" +
|
|
"\x15RULE_MODE_UNSPECIFIED\x10\x00\x12\x10\n" +
|
|
"\fEVENT_DRIVEN\x10\x01\x12\x10\n" +
|
|
"\fSCAN_AT_DATE\x10\x02\x12\r\n" +
|
|
"\tSCAN_ONLY\x10\x03\x12\f\n" +
|
|
"\bDISABLED\x10\x04\x12\x15\n" +
|
|
"\x11PENDING_BOOTSTRAP\x10\x05\"\xa6\x01\n" +
|
|
"\x0eDegradedReason\x12\x1f\n" +
|
|
"\x1bDEGRADED_REASON_UNSPECIFIED\x10\x00\x12\f\n" +
|
|
"\bLAG_HIGH\x10\x01\x12\x10\n" +
|
|
"\fPENDING_FULL\x10\x02\x12\x13\n" +
|
|
"\x0fDELETE_FAILURES\x10\x03\x12\x13\n" +
|
|
"\x0fOPERATOR_PAUSED\x10\x04\x12\x1b\n" +
|
|
"\x17RETENTION_BELOW_HORIZON\x10\x05\x12\f\n" +
|
|
"\bLOST_LOG\x10\x06\"\xb6\x01\n" +
|
|
"\vPendingItem\x12\x1f\n" +
|
|
"\vobject_path\x18\x01 \x01(\tR\n" +
|
|
"objectPath\x12\x1d\n" +
|
|
"\n" +
|
|
"version_id\x18\x02 \x01(\tR\tversionId\x12\x1a\n" +
|
|
"\tdue_at_ns\x18\x03 \x01(\x03R\adueAtNs\x12K\n" +
|
|
"\x11expected_identity\x18\x04 \x01(\v2\x1e.s3_lifecycle_pb.EntryIdentityR\x10expectedIdentity\"\x88\x01\n" +
|
|
"\x0eBootstrapState\x12*\n" +
|
|
"\x11last_scanned_path\x18\x01 \x01(\tR\x0flastScannedPath\x12\"\n" +
|
|
"\rstarted_at_ns\x18\x02 \x01(\x03R\vstartedAtNs\x12&\n" +
|
|
"\x0fcompleted_at_ns\x18\x03 \x01(\x03R\rcompletedAtNs\"\x83\x04\n" +
|
|
"\vReaderState\x124\n" +
|
|
"\x16primary_filer_endpoint\x18\x01 \x01(\tR\x14primaryFilerEndpoint\x12o\n" +
|
|
"\x17last_processed_original\x18\x02 \x03(\v27.s3_lifecycle_pb.ReaderState.LastProcessedOriginalEntryR\x15lastProcessedOriginal\x12[\n" +
|
|
"\x18last_processed_predicate\x18\x03 \x03(\v2!.s3_lifecycle_pb.FilerShardCursorR\x16lastProcessedPredicate\x12Q\n" +
|
|
"\x14tail_drained_streams\x18\x04 \x03(\v2\x1f.s3_lifecycle_pb.TailDrainedKeyR\x12tailDrainedStreams\x12,\n" +
|
|
"\x12last_checkpoint_ns\x18\x05 \x01(\x03R\x10lastCheckpointNs\x1ao\n" +
|
|
"\x1aLastProcessedOriginalEntry\x12\x10\n" +
|
|
"\x03key\x18\x01 \x01(\x03R\x03key\x12;\n" +
|
|
"\x05value\x18\x02 \x01(\v2%.s3_lifecycle_pb.FilerShardCursorListR\x05value:\x028\x01\"S\n" +
|
|
"\x14FilerShardCursorList\x12;\n" +
|
|
"\acursors\x18\x01 \x03(\v2!.s3_lifecycle_pb.FilerShardCursorR\acursors\"\x8e\x01\n" +
|
|
"\x0eTailDrainedKey\x12<\n" +
|
|
"\vstream_kind\x18\x01 \x01(\x0e2\x1b.s3_lifecycle_pb.StreamKindR\n" +
|
|
"streamKind\x12\x19\n" +
|
|
"\bfiler_id\x18\x02 \x01(\tR\afilerId\x12#\n" +
|
|
"\rdelay_seconds\x18\x03 \x01(\x03R\fdelaySeconds\"\xa3\x04\n" +
|
|
"\rBlockerRecord\x12<\n" +
|
|
"\vstream_kind\x18\x01 \x01(\x0e2\x1b.s3_lifecycle_pb.StreamKindR\n" +
|
|
"streamKind\x12\x14\n" +
|
|
"\x05shard\x18\x02 \x01(\tR\x05shard\x12#\n" +
|
|
"\rdelay_seconds\x18\x03 \x01(\x03R\fdelaySeconds\x12<\n" +
|
|
"\bposition\x18\x04 \x01(\v2 .s3_lifecycle_pb.MessagePositionR\bposition\x12\x1b\n" +
|
|
"\trule_hash\x18\x05 \x01(\fR\bruleHash\x12\x16\n" +
|
|
"\x06bucket\x18\x06 \x01(\tR\x06bucket\x12\x1f\n" +
|
|
"\vobject_path\x18\a \x01(\tR\n" +
|
|
"objectPath\x12\x1d\n" +
|
|
"\n" +
|
|
"version_id\x18\b \x01(\tR\tversionId\x12<\n" +
|
|
"\vaction_kind\x18\x0e \x01(\x0e2\x1b.s3_lifecycle_pb.ActionKindR\n" +
|
|
"actionKind\x12\x16\n" +
|
|
"\x06reason\x18\t \x01(\tR\x06reason\x12\x1d\n" +
|
|
"\n" +
|
|
"last_error\x18\n" +
|
|
" \x01(\tR\tlastError\x12'\n" +
|
|
"\x10first_seen_at_ns\x18\v \x01(\x03R\rfirstSeenAtNs\x12'\n" +
|
|
"\x10last_retry_at_ns\x18\f \x01(\x03R\rlastRetryAtNs\x12\x1f\n" +
|
|
"\vretry_count\x18\r \x01(\x05R\n" +
|
|
"retryCount\"\x85\x02\n" +
|
|
"\tStreamKey\x12:\n" +
|
|
"\boriginal\x18\x01 \x01(\v2\x1c.s3_lifecycle_pb.OriginalKeyH\x00R\boriginal\x12=\n" +
|
|
"\tpredicate\x18\x02 \x01(\v2\x1d.s3_lifecycle_pb.PredicateKeyH\x00R\tpredicate\x12=\n" +
|
|
"\tbootstrap\x18\x03 \x01(\v2\x1d.s3_lifecycle_pb.BootstrapKeyH\x00R\tbootstrap\x127\n" +
|
|
"\apending\x18\x04 \x01(\v2\x1b.s3_lifecycle_pb.PendingKeyH\x00R\apendingB\x05\n" +
|
|
"\x03key\"\x86\x01\n" +
|
|
"\vOriginalKey\x12\x14\n" +
|
|
"\x05shard\x18\x01 \x01(\tR\x05shard\x12#\n" +
|
|
"\rdelay_seconds\x18\x02 \x01(\x03R\fdelaySeconds\x12<\n" +
|
|
"\bposition\x18\x03 \x01(\v2 .s3_lifecycle_pb.MessagePositionR\bposition\"b\n" +
|
|
"\fPredicateKey\x12\x14\n" +
|
|
"\x05shard\x18\x01 \x01(\tR\x05shard\x12<\n" +
|
|
"\bposition\x18\x02 \x01(\v2 .s3_lifecycle_pb.MessagePositionR\bposition\"\xc1\x01\n" +
|
|
"\fBootstrapKey\x12\x16\n" +
|
|
"\x06bucket\x18\x01 \x01(\tR\x06bucket\x12\x1f\n" +
|
|
"\vobject_path\x18\x02 \x01(\tR\n" +
|
|
"objectPath\x12\x1d\n" +
|
|
"\n" +
|
|
"version_id\x18\x03 \x01(\tR\tversionId\x12\x1b\n" +
|
|
"\trule_hash\x18\x04 \x01(\fR\bruleHash\x12<\n" +
|
|
"\vaction_kind\x18\x05 \x01(\x0e2\x1b.s3_lifecycle_pb.ActionKindR\n" +
|
|
"actionKind\"\xbf\x01\n" +
|
|
"\n" +
|
|
"PendingKey\x12\x16\n" +
|
|
"\x06bucket\x18\x01 \x01(\tR\x06bucket\x12\x1b\n" +
|
|
"\trule_hash\x18\x02 \x01(\fR\bruleHash\x12\x1f\n" +
|
|
"\vobject_path\x18\x03 \x01(\tR\n" +
|
|
"objectPath\x12\x1d\n" +
|
|
"\n" +
|
|
"version_id\x18\x04 \x01(\tR\tversionId\x12<\n" +
|
|
"\vaction_kind\x18\x05 \x01(\x0e2\x1b.s3_lifecycle_pb.ActionKindR\n" +
|
|
"actionKind\"\xc3\x01\n" +
|
|
"\x10RetryBudgetEntry\x12,\n" +
|
|
"\x03key\x18\x01 \x01(\v2\x1a.s3_lifecycle_pb.StreamKeyR\x03key\x12/\n" +
|
|
"\x13consecutive_retries\x18\x02 \x01(\x05R\x12consecutiveRetries\x12'\n" +
|
|
"\x10first_seen_at_ns\x18\x03 \x01(\x03R\rfirstSeenAtNs\x12'\n" +
|
|
"\x10last_retry_at_ns\x18\x04 \x01(\x03R\rlastRetryAtNs\"\xee\x01\n" +
|
|
"\vRetryTarget\x12,\n" +
|
|
"\x03key\x18\x01 \x01(\v2\x1a.s3_lifecycle_pb.StreamKeyR\x03key\x12\x16\n" +
|
|
"\x06bucket\x18\x02 \x01(\tR\x06bucket\x12\x1f\n" +
|
|
"\vobject_path\x18\x03 \x01(\tR\n" +
|
|
"objectPath\x12\x1d\n" +
|
|
"\n" +
|
|
"version_id\x18\x04 \x01(\tR\tversionId\x12\x1b\n" +
|
|
"\trule_hash\x18\x05 \x01(\fR\bruleHash\x12<\n" +
|
|
"\vaction_kind\x18\x06 \x01(\x0e2\x1b.s3_lifecycle_pb.ActionKindR\n" +
|
|
"actionKind*\xa8\x01\n" +
|
|
"\n" +
|
|
"ActionKind\x12\x1b\n" +
|
|
"\x17ACTION_KIND_UNSPECIFIED\x10\x00\x12\x13\n" +
|
|
"\x0fEXPIRATION_DAYS\x10\x01\x12\x13\n" +
|
|
"\x0fEXPIRATION_DATE\x10\x02\x12\x13\n" +
|
|
"\x0fNONCURRENT_DAYS\x10\x03\x12\x14\n" +
|
|
"\x10NEWER_NONCURRENT\x10\x04\x12\r\n" +
|
|
"\tABORT_MPU\x10\x05\x12\x19\n" +
|
|
"\x15EXPIRED_DELETE_MARKER\x10\x06*\x96\x01\n" +
|
|
"\x16LifecycleDeleteOutcome\x12(\n" +
|
|
"$LIFECYCLE_DELETE_OUTCOME_UNSPECIFIED\x10\x00\x12\b\n" +
|
|
"\x04DONE\x10\x01\x12\x11\n" +
|
|
"\rNOOP_RESOLVED\x10\x02\x12\x17\n" +
|
|
"\x13SKIPPED_OBJECT_LOCK\x10\x03\x12\x0f\n" +
|
|
"\vRETRY_LATER\x10\x04\x12\v\n" +
|
|
"\aBLOCKED\x10\x05*b\n" +
|
|
"\n" +
|
|
"StreamKind\x12\x1b\n" +
|
|
"\x17STREAM_KIND_UNSPECIFIED\x10\x00\x12\f\n" +
|
|
"\bORIGINAL\x10\x01\x12\r\n" +
|
|
"\tPREDICATE\x10\x02\x12\r\n" +
|
|
"\tBOOTSTRAP\x10\x03\x12\v\n" +
|
|
"\aPENDING\x10\x042\x82\x01\n" +
|
|
"\x1aSeaweedS3LifecycleInternal\x12d\n" +
|
|
"\x0fLifecycleDelete\x12'.s3_lifecycle_pb.LifecycleDeleteRequest\x1a(.s3_lifecycle_pb.LifecycleDeleteResponseB\\\n" +
|
|
"\x10seaweedfs.clientB\x10S3LifecycleProtoZ6github.com/seaweedfs/seaweedfs/weed/pb/s3_lifecycle_pbb\x06proto3"
|
|
|
|
var (
|
|
file_s3_lifecycle_proto_rawDescOnce sync.Once
|
|
file_s3_lifecycle_proto_rawDescData []byte
|
|
)
|
|
|
|
func file_s3_lifecycle_proto_rawDescGZIP() []byte {
|
|
file_s3_lifecycle_proto_rawDescOnce.Do(func() {
|
|
file_s3_lifecycle_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_s3_lifecycle_proto_rawDesc), len(file_s3_lifecycle_proto_rawDesc)))
|
|
})
|
|
return file_s3_lifecycle_proto_rawDescData
|
|
}
|
|
|
|
var file_s3_lifecycle_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
|
|
var file_s3_lifecycle_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
|
|
var file_s3_lifecycle_proto_goTypes = []any{
|
|
(ActionKind)(0), // 0: s3_lifecycle_pb.ActionKind
|
|
(LifecycleDeleteOutcome)(0), // 1: s3_lifecycle_pb.LifecycleDeleteOutcome
|
|
(StreamKind)(0), // 2: s3_lifecycle_pb.StreamKind
|
|
(LifecycleState_RuleMode)(0), // 3: s3_lifecycle_pb.LifecycleState.RuleMode
|
|
(LifecycleState_DegradedReason)(0), // 4: s3_lifecycle_pb.LifecycleState.DegradedReason
|
|
(*LifecycleDeleteRequest)(nil), // 5: s3_lifecycle_pb.LifecycleDeleteRequest
|
|
(*LifecycleDeleteResponse)(nil), // 6: s3_lifecycle_pb.LifecycleDeleteResponse
|
|
(*MessagePosition)(nil), // 7: s3_lifecycle_pb.MessagePosition
|
|
(*FilerShardCursor)(nil), // 8: s3_lifecycle_pb.FilerShardCursor
|
|
(*EntryIdentity)(nil), // 9: s3_lifecycle_pb.EntryIdentity
|
|
(*LifecycleState)(nil), // 10: s3_lifecycle_pb.LifecycleState
|
|
(*PendingItem)(nil), // 11: s3_lifecycle_pb.PendingItem
|
|
(*BootstrapState)(nil), // 12: s3_lifecycle_pb.BootstrapState
|
|
(*ReaderState)(nil), // 13: s3_lifecycle_pb.ReaderState
|
|
(*FilerShardCursorList)(nil), // 14: s3_lifecycle_pb.FilerShardCursorList
|
|
(*TailDrainedKey)(nil), // 15: s3_lifecycle_pb.TailDrainedKey
|
|
(*BlockerRecord)(nil), // 16: s3_lifecycle_pb.BlockerRecord
|
|
(*StreamKey)(nil), // 17: s3_lifecycle_pb.StreamKey
|
|
(*OriginalKey)(nil), // 18: s3_lifecycle_pb.OriginalKey
|
|
(*PredicateKey)(nil), // 19: s3_lifecycle_pb.PredicateKey
|
|
(*BootstrapKey)(nil), // 20: s3_lifecycle_pb.BootstrapKey
|
|
(*PendingKey)(nil), // 21: s3_lifecycle_pb.PendingKey
|
|
(*RetryBudgetEntry)(nil), // 22: s3_lifecycle_pb.RetryBudgetEntry
|
|
(*RetryTarget)(nil), // 23: s3_lifecycle_pb.RetryTarget
|
|
nil, // 24: s3_lifecycle_pb.ReaderState.LastProcessedOriginalEntry
|
|
}
|
|
var file_s3_lifecycle_proto_depIdxs = []int32{
|
|
0, // 0: s3_lifecycle_pb.LifecycleDeleteRequest.action_kind:type_name -> s3_lifecycle_pb.ActionKind
|
|
9, // 1: s3_lifecycle_pb.LifecycleDeleteRequest.expected_identity:type_name -> s3_lifecycle_pb.EntryIdentity
|
|
1, // 2: s3_lifecycle_pb.LifecycleDeleteResponse.outcome:type_name -> s3_lifecycle_pb.LifecycleDeleteOutcome
|
|
7, // 3: s3_lifecycle_pb.FilerShardCursor.position:type_name -> s3_lifecycle_pb.MessagePosition
|
|
0, // 4: s3_lifecycle_pb.LifecycleState.action_kind:type_name -> s3_lifecycle_pb.ActionKind
|
|
3, // 5: s3_lifecycle_pb.LifecycleState.mode:type_name -> s3_lifecycle_pb.LifecycleState.RuleMode
|
|
4, // 6: s3_lifecycle_pb.LifecycleState.degraded_reason:type_name -> s3_lifecycle_pb.LifecycleState.DegradedReason
|
|
9, // 7: s3_lifecycle_pb.PendingItem.expected_identity:type_name -> s3_lifecycle_pb.EntryIdentity
|
|
24, // 8: s3_lifecycle_pb.ReaderState.last_processed_original:type_name -> s3_lifecycle_pb.ReaderState.LastProcessedOriginalEntry
|
|
8, // 9: s3_lifecycle_pb.ReaderState.last_processed_predicate:type_name -> s3_lifecycle_pb.FilerShardCursor
|
|
15, // 10: s3_lifecycle_pb.ReaderState.tail_drained_streams:type_name -> s3_lifecycle_pb.TailDrainedKey
|
|
8, // 11: s3_lifecycle_pb.FilerShardCursorList.cursors:type_name -> s3_lifecycle_pb.FilerShardCursor
|
|
2, // 12: s3_lifecycle_pb.TailDrainedKey.stream_kind:type_name -> s3_lifecycle_pb.StreamKind
|
|
2, // 13: s3_lifecycle_pb.BlockerRecord.stream_kind:type_name -> s3_lifecycle_pb.StreamKind
|
|
7, // 14: s3_lifecycle_pb.BlockerRecord.position:type_name -> s3_lifecycle_pb.MessagePosition
|
|
0, // 15: s3_lifecycle_pb.BlockerRecord.action_kind:type_name -> s3_lifecycle_pb.ActionKind
|
|
18, // 16: s3_lifecycle_pb.StreamKey.original:type_name -> s3_lifecycle_pb.OriginalKey
|
|
19, // 17: s3_lifecycle_pb.StreamKey.predicate:type_name -> s3_lifecycle_pb.PredicateKey
|
|
20, // 18: s3_lifecycle_pb.StreamKey.bootstrap:type_name -> s3_lifecycle_pb.BootstrapKey
|
|
21, // 19: s3_lifecycle_pb.StreamKey.pending:type_name -> s3_lifecycle_pb.PendingKey
|
|
7, // 20: s3_lifecycle_pb.OriginalKey.position:type_name -> s3_lifecycle_pb.MessagePosition
|
|
7, // 21: s3_lifecycle_pb.PredicateKey.position:type_name -> s3_lifecycle_pb.MessagePosition
|
|
0, // 22: s3_lifecycle_pb.BootstrapKey.action_kind:type_name -> s3_lifecycle_pb.ActionKind
|
|
0, // 23: s3_lifecycle_pb.PendingKey.action_kind:type_name -> s3_lifecycle_pb.ActionKind
|
|
17, // 24: s3_lifecycle_pb.RetryBudgetEntry.key:type_name -> s3_lifecycle_pb.StreamKey
|
|
17, // 25: s3_lifecycle_pb.RetryTarget.key:type_name -> s3_lifecycle_pb.StreamKey
|
|
0, // 26: s3_lifecycle_pb.RetryTarget.action_kind:type_name -> s3_lifecycle_pb.ActionKind
|
|
14, // 27: s3_lifecycle_pb.ReaderState.LastProcessedOriginalEntry.value:type_name -> s3_lifecycle_pb.FilerShardCursorList
|
|
5, // 28: s3_lifecycle_pb.SeaweedS3LifecycleInternal.LifecycleDelete:input_type -> s3_lifecycle_pb.LifecycleDeleteRequest
|
|
6, // 29: s3_lifecycle_pb.SeaweedS3LifecycleInternal.LifecycleDelete:output_type -> s3_lifecycle_pb.LifecycleDeleteResponse
|
|
29, // [29:30] is the sub-list for method output_type
|
|
28, // [28:29] is the sub-list for method input_type
|
|
28, // [28:28] is the sub-list for extension type_name
|
|
28, // [28:28] is the sub-list for extension extendee
|
|
0, // [0:28] is the sub-list for field type_name
|
|
}
|
|
|
|
func init() { file_s3_lifecycle_proto_init() }
|
|
func file_s3_lifecycle_proto_init() {
|
|
if File_s3_lifecycle_proto != nil {
|
|
return
|
|
}
|
|
file_s3_lifecycle_proto_msgTypes[12].OneofWrappers = []any{
|
|
(*StreamKey_Original)(nil),
|
|
(*StreamKey_Predicate)(nil),
|
|
(*StreamKey_Bootstrap)(nil),
|
|
(*StreamKey_Pending)(nil),
|
|
}
|
|
type x struct{}
|
|
out := protoimpl.TypeBuilder{
|
|
File: protoimpl.DescBuilder{
|
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_s3_lifecycle_proto_rawDesc), len(file_s3_lifecycle_proto_rawDesc)),
|
|
NumEnums: 5,
|
|
NumMessages: 20,
|
|
NumExtensions: 0,
|
|
NumServices: 1,
|
|
},
|
|
GoTypes: file_s3_lifecycle_proto_goTypes,
|
|
DependencyIndexes: file_s3_lifecycle_proto_depIdxs,
|
|
EnumInfos: file_s3_lifecycle_proto_enumTypes,
|
|
MessageInfos: file_s3_lifecycle_proto_msgTypes,
|
|
}.Build()
|
|
File_s3_lifecycle_proto = out.File
|
|
file_s3_lifecycle_proto_goTypes = nil
|
|
file_s3_lifecycle_proto_depIdxs = nil
|
|
}
|