Skip to main content

LocalFsStore

Struct LocalFsStore 

Source
pub struct LocalFsStore { /* private fields */ }

Implementations§

Source§

impl LocalFsStore

Source

pub fn create_environment( &self, env_id: &EnvId, name: String, host_config: EnvironmentHostConfig, ) -> Result<Environment, StoreError>

Create a fresh environment with empty bundles/revisions/packs. Rejects (via StoreError::Conflict) if the env already exists — callers wanting upsert semantics should call Self::update_environment.

The caller’s EnvironmentHostConfig::env_id is overwritten with env_id so the on-disk row’s host-config envelope cannot disagree with the directory it lands in.

Source

pub fn update_environment( &self, env_id: &EnvId, patch: UpdateEnvironmentPayload, ) -> Result<Environment, StoreError>

Patch the named scalar fields on an existing env. [FieldUpdate::Keep] fields are skipped, [FieldUpdate::Set] writes the new value, and [FieldUpdate::Clear] resets an optional field to None. Returns the fully-updated Environment. Collapses what was previously split across the op env update, op env set-public-url, and op config set verbs — see UpdateEnvironmentPayload for the rationale.

StoreError::NotFound passes through unchanged; the CLI mapper downcasts it to OpError::NotFound via [crate::cli::map_store_err_preserving_noun].

Source

pub fn migrate_merge_bindings( &self, target_env_id: &EnvId, payload: MigrateMergePayload, ) -> Result<(Vec<String>, Vec<String>), StoreError>

Merge pack bindings and extension bindings into target_env_id, optionally seeding a fresh target env from a source when the target doesn’t exist yet. All work runs under the target’s flock so the existence check + optional seed + merge + save are atomic.

Skips slots already in the target’s packs and extension keys already in the target’s extensions (uniqueness on (kind.path(), instance_id)). Returns (merged_slot_names, merged_extension_key_strings).

Returns StoreError::NotFound if target is missing AND payload.seed_if_missing is None (the caller asserted target presence).

Source

pub fn stage_revision( &self, env_id: &EnvId, payload: StageRevisionPayload, _idempotency_key: IdempotencyKey, ) -> Result<Revision, StoreError>

Stage a fresh revision under payload.deployment_id. The caller supplies the pre-resolved artifact pointers (bundle_digest, pack_list, pack_list_lock_ref, pack_config_refs) and a pre-minted RevisionId — bundle staging (extract + lock-pin + pack-config materialization) runs OUTSIDE the env flock because the rev_dir is named after the ULID and the extraction cost shouldn’t hold the lock.

Inside the flock: load → re-validate deployment exists → compute next_sequence = max(existing[deployment]) + 1 → build Revision (Staged) → push → save.

Returns StoreError::DependentNotFound when the deployment is missing under the env at lock-acquisition time (closes the TOCTOU window over any pre-call lookup the caller may have done for input validation).

payload.idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn warm_revision( &self, env_id: &EnvId, payload: WarmRevisionPayload, _idempotency_key: IdempotencyKey, ) -> Result<RevisionTransitionOutcome, StoreError>

Drive a revision through the Staged → Warming → Ready chain and apply the client-evaluated warm/ready health-gate outcome. The chain advance, the warmed_at stamp, the gate-result application (Ready on Ok(()); Failed on Err(failure), persisted), and the runtime-config.json refresh all happen inside one super::store::LocalFsStore::transact flock so the on-disk env is durable when the call returns.

The lifecycle precondition (payload.expected_lifecycle, PR-3a.6b), the chain constants, and the gate semantics live in engine::warm_revision — shared verbatim with the operator-store-server.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn drain_revision( &self, env_id: &EnvId, revision_id: RevisionId, _idempotency_key: IdempotencyKey, ) -> Result<RevisionTransitionOutcome, StoreError>

Transition a Ready revision to Draining. Pure lifecycle stamp — the in-flight drain dance (sessions, WebSocket cleanup) is owned by greentic-start.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn archive_revision( &self, env_id: &EnvId, revision_id: RevisionId, _idempotency_key: IdempotencyKey, ) -> Result<RevisionTransitionOutcome, StoreError>

Archive a revision, walking any of Staged | Warming | Ready | Failed to Archived in one hop and the post-drain Draining → Inactive → Archived walk end-to-end. Refuses if the revision still routes live traffic — callers rebalance via gtc op traffic set first.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn add_bundle( &self, env_id: &EnvId, payload: AddBundlePayload, _idempotency_key: IdempotencyKey, ) -> Result<BundleDeployment, StoreError>

Add a BundleDeployment to the env. Rejects with StoreError::Conflict when (bundle_id, customer_id) is already deployed (verb semantics live in engine::add_bundle). Writes the v1 revenue-policy sidecar via super::write_revenue_policy_version and pins the resulting ref on the deployment.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn update_bundle( &self, env_id: &EnvId, payload: UpdateBundlePayload, _idempotency_key: IdempotencyKey, ) -> Result<BundleDeployment, StoreError>

Patch a BundleDeployment’s scalar fields. None fields are skipped (verb semantics live in engine::update_bundle). When revenue_share is Some, writes a new signed/versioned revenue-policy sidecar (chain-linked to the prior version) and pins the new ref on the deployment.

Returns StoreError::DependentNotFound when deployment_id is absent under the env at lock-acquisition time.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn remove_bundle( &self, env_id: &EnvId, deployment_id: DeploymentId, _idempotency_key: IdempotencyKey, ) -> Result<RemoveBundleOutcome, StoreError>

Remove a BundleDeployment from the env. Refuses with StoreError::Conflict if the deployment still carries live state (any greentic_deploy_spec::TrafficSplit pointing at it, or any non-Archived revision under it) — callers run op traffic clear and archive revisions first. Drops archived revisions for the same deployment_id so the env stays compact. Verb semantics live in engine::remove_bundle; this wrapper owns the flock + persistence.

Returns StoreError::DependentNotFound when the deployment is absent under the env at lock-acquisition time (matches the DependentNotFound precedent set by stage_revision).

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn add_pack_binding( &self, env_id: &EnvId, binding: EnvPackBinding, _idempotency_key: IdempotencyKey, ) -> Result<EnvPackBinding, StoreError>

Bind a new env-pack slot. Rejects with StoreError::Conflict when the slot is already bound (callers should update instead). Verb semantics live in engine::add_pack_binding; this wrapper owns the flock + persistence.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn update_pack_binding( &self, env_id: &EnvId, slot: CapabilitySlot, binding: EnvPackBinding, _idempotency_key: IdempotencyKey, ) -> Result<(EnvPackBinding, u64), StoreError>

Replace the binding on an existing slot. The engine snapshots the prior binding inline (one-step-rollback stash) — see engine::update_pack_binding.

Returns (new_binding, new_generation).

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn remove_pack_binding( &self, env_id: &EnvId, slot: CapabilitySlot, _idempotency_key: IdempotencyKey, ) -> Result<(EnvPackBinding, u64), StoreError>

Remove a pack-binding slot. Returns (removed_binding, removed_generation).

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn rollback_pack_binding( &self, env_id: &EnvId, slot: CapabilitySlot, _idempotency_key: IdempotencyKey, ) -> Result<(EnvPackBinding, u64), StoreError>

Rollback a pack-binding slot to its one-step-previous snapshot. Returns (restored_binding, new_generation). Fails with StoreError::DependentNotFound when the slot doesn’t exist and StoreError::Conflict when there is no previous snapshot to restore.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn bootstrap_trust_root( &self, env_id: &EnvId, ) -> Result<TrustRootSeed, StoreError>

Unconditional re-grant: load (or generate) the operator key and add it to the env trust root. Idempotent on case-insensitive key_id collision — the existing entry’s PEM is overwritten with whatever the operator-key file holds today.

Lock placement. operator_key::load_or_generate runs OUTSIDE the env flock so a slow OS RNG seed does not hold the lock; the trust-root mutation runs INSIDE the flock so concurrent add/remove cannot race the read-modify-write. Caller is responsible for any authz gate before invoking this method — ~/.greentic/operator/key.pem is generated on first call to load_or_generate, so an authz failure after this method runs would not roll back that side effect.

Source

pub fn seed_trust_root_if_absent( &self, env_id: &EnvId, ) -> Result<Option<TrustRootSeed>, StoreError>

First-init-only variant: returns None when <env_dir>/trust-root.json already exists (operator has touched the trust root via bootstrap/add/remove). The existence check and load_or_generate both sit under the env flock so a concurrent trust-root remove cannot race the gate, and ~/.greentic/operator/key.pem is not auto-generated when the gate would skip.

Source

pub fn add_trusted_key( &self, env_id: &EnvId, key_id: String, public_key_pem: String, _idempotency_key: IdempotencyKey, ) -> Result<TrustRootAddOutcome, StoreError>

Add a trusted (key_id, public_key_pem) entry to the env trust root. Validates key_id matches the canonical derivation from pem and rejects empty/whitespace key ids. Idempotent on case-insensitive key_id collision.

_idempotency_key is accepted for trait-conformance with super::mutations::EnvironmentMutations::add_trusted_key and ignored locally — the HTTP backend caches it for A8 §2 replay.

Source

pub fn remove_trusted_key( &self, env_id: &EnvId, key_id: String, _idempotency_key: IdempotencyKey, ) -> Result<TrustRootRemoveOutcome, StoreError>

Remove a trusted key by case-insensitive key_id. Silent no-op when the id is absent. Captures the pre-state PEM under the flock for race-safe recovery reporting.

_idempotency_key is accepted for trait-conformance with super::mutations::EnvironmentMutations::remove_trusted_key and ignored locally. The HTTP backend MUST cache and replay the original outcome so retries don’t surface removed_public_key_pem: None (the failure mode that motivated requiring the key).

Source

pub fn add_extension_binding( &self, env_id: &EnvId, binding: ExtensionBinding, _idempotency_key: IdempotencyKey, ) -> Result<ExtensionBinding, StoreError>

Add a new extension binding to the env. Rejects with StoreError::Conflict if a binding with the same (kind.path(), instance_id) key already exists — callers wanting to replace use Self::update_extension_binding. Verb semantics live in engine::add_extension_binding.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn update_extension_binding( &self, env_id: &EnvId, key: ExtensionKey, binding: ExtensionBinding, _idempotency_key: IdempotencyKey, ) -> Result<(ExtensionBinding, u64), StoreError>

Replace an existing extension binding identified by key. The engine bumps generation and stashes the prior binding inline so Self::rollback_extension_binding can restore it — see engine::update_extension_binding.

Returns (new_binding, new_generation).

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn remove_extension_binding( &self, env_id: &EnvId, key: ExtensionKey, _idempotency_key: IdempotencyKey, ) -> Result<(ExtensionBinding, u64), StoreError>

Remove an extension binding identified by key. Returns the removed binding and its generation at the time of removal.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn rollback_extension_binding( &self, env_id: &EnvId, key: ExtensionKey, _idempotency_key: IdempotencyKey, ) -> Result<(ExtensionBinding, u64), StoreError>

Rollback an extension binding to its previous version. Requires the binding to have a stashed previous_binding_ref. Bumps generation and clears the stash so a second rollback fails (single-step only).

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn set_traffic_split( &self, env_id: &EnvId, payload: SetTrafficSplitPayload, idempotency_key: IdempotencyKey, ) -> Result<ApplyTrafficSplitOutcome, StoreError>

Replace the entire traffic-split entry list for one deployment. Pure semantics (10,000 bps sum invariant, §5.3 admission, the idempotency contract, the one-step rollback stash) live in engine::set_traffic_split; this wrapper owns persistence and the derived runtime-config.json.

Post-save, the materialized runtime-config.json is refreshed. A failure there wraps as StoreError::CommittedAfterSave so the CLI audit fires for the already-persisted mutation. The idempotent no-op replay skips the save but still reconciles runtime-config (repairs a prior publish failure) — a refresh failure there is NOT committed-after-save, because nothing new was committed.

TrafficSplitApplied telemetry is emitted by the CLI layer from the outcome’s env snapshot (identical local and remote), not here.

Source

pub fn rollback_traffic_split( &self, env_id: &EnvId, deployment_id: DeploymentId, _idempotency_key: IdempotencyKey, ) -> Result<RollbackTrafficSplitOutcome, StoreError>

Rollback the traffic split for a deployment to its one-step-previous snapshot. Pure semantics live in engine::rollback_traffic_split; this wrapper owns persistence and the runtime-config.json refresh (wrapped as StoreError::CommittedAfterSave post-save).

Returns StoreError::DependentNotFound when no split exists for the deployment, and StoreError::Conflict when there is no previous snapshot to restore.

_idempotency_key is accepted for trait conformance and ignored locally; the HTTP backend caches it for A8 §2 replay.

Source

pub fn add_messaging_endpoint( &self, env_id: &EnvId, payload: AddMessagingEndpointPayload, idempotency_key: IdempotencyKey, ) -> Result<MessagingEndpoint, StoreError>

Add a messaging endpoint. Rejects with StoreError::Conflict when the (provider_type, provider_id) pair is already present or when the idempotency key was already used for a different endpoint identity. Idempotent on same-key same-identity replay (repairs a stale projection from a prior failed call).

Telegram-class providers auto-generate a webhook secret at creation time via [crate::cli::messaging::provision_webhook_secret].

Link a bundle to an existing messaging endpoint. Idempotent when the bundle is already linked (repairs a stale projection). Rejects with StoreError::DependentNotFound when the endpoint or bundle is missing.

Unlink a bundle from an existing messaging endpoint. Idempotent when the bundle is not linked (repairs a stale projection). Rejects with StoreError::Conflict if the bundle owns the endpoint’s welcome_flow.

Source

pub fn set_messaging_welcome_flow( &self, env_id: &EnvId, payload: SetMessagingWelcomeFlowPayload, idempotency_key: IdempotencyKey, ) -> Result<MessagingEndpoint, StoreError>

Set the welcome flow on a messaging endpoint. Rejects with StoreError::InvalidArgument when the bundle is not linked, or when pack_id does not appear in any current revision’s pack_list. Idempotent when the same welcome flow ref is already set (repairs a stale projection).

Source

pub fn remove_messaging_endpoint( &self, env_id: &EnvId, endpoint_id: MessagingEndpointId, ) -> Result<MessagingEndpointId, StoreError>

Remove a messaging endpoint by id. Idempotent when the endpoint is already absent (repairs a stale projection). Returns the id of the removed endpoint.

Source

pub fn rotate_messaging_webhook_secret( &self, env_id: &EnvId, endpoint_id: MessagingEndpointId, updated_by: String, idempotency_key: IdempotencyKey, ) -> Result<MessagingEndpoint, StoreError>

Rotate the webhook secret for a messaging endpoint. Generates a new CSPRNG secret value, writes it to the dev-store under the existing (or freshly-built) secret ref URI, and bumps generation. Idempotent on same-idem-key replay (returns the existing endpoint without re-generating).

Source

pub fn ensure_local_environment( &self, env_id: &EnvId, payload: EnsureLocalEnvironmentPayload, ) -> Result<(Environment, LocalEnvOutcome), StoreError>

Get-or-create-with-heal: idempotent first-run bootstrap of the local Environment with default env-pack bindings. Returns the env + an outcome variant indicating whether it was Created, Healed (default bindings added), or AlreadyExists (no change needed).

The entire read-modify-write runs inside LocalFsStore::transact, so concurrent first-run invocations on the same host serialize on the per-env flock and produce a single env.

refresh_local_runtime_stub is NOT called here — the CLI layer runs it after the verb returns, outside the flock. The tiny race window (another writer could modify the env between verb-return and stub-refresh) is acceptable because the runtime stub is a derived projection that self-heals on every bootstrap call.

This verb is not part of the super::mutations::EnvironmentMutations trait — bootstrap is LocalFsStore-specific. Remote stores don’t run first-run local bootstrap.

Source§

impl LocalFsStore

Source

pub fn new(root: impl Into<PathBuf>) -> Self

Source

pub fn default_root() -> Option<PathBuf>

~/.greentic/environments per the Phase A acceptance criteria.

Source

pub fn root(&self) -> &Path

Source

pub fn load_update_channel( &self, env_id: &EnvId, ) -> Result<Option<UpdateChannelConfig>, StoreError>

Load the operator’s update-channel policy. Absent file → Ok(None) (callers resolve that to deny-by-default). Validates the env-id binding and schema discriminator, mirroring load_runtime. Inherent (not a trait method): the update channel is a local-runtime concern, so remote store backends need not carry it.

Source§

impl LocalFsStore

Source

pub fn env_lock_path(&self, env_id: &EnvId) -> Result<PathBuf, StoreError>

Resolve the per-env lock path. Public so external callers that need raw EnvFlock semantics can grab the path without poking at private internals — but they must understand that each mutating call already re-acquires this lock blocking, so externally-held guards combined with save_* on the same instance will deadlock. Prefer LocalFsStore::transact for compound mutations.

Source

pub fn transact<F, R, E>(&self, env_id: &EnvId, f: F) -> Result<R, E>
where F: FnOnce(&Locked<'_>) -> Result<R, E>, E: From<StoreError>,

Run f while holding the env’s exclusive lock. The closure receives a Locked view whose mutator methods skip lock acquisition, so a natural load → mutate → save flow inside the closure does not re-enter (and deadlock on) the per-FD flock.

Reads (load, load_runtime, load_pack_answers, exists, list) do not take the lock and are also available on the Locked handle for convenience.

Generic over the closure’s error type via E: From<StoreError> so callers that mix storage errors with their own domain errors (e.g. the cli::* operator surface using OpError) can run validation + load + mutate + save in a single critical section without an outer-layer error-mapping dance. Existing callers passing Result<_, StoreError> continue to work because From<StoreError> for StoreError is automatic.

Trait Implementations§

Source§

impl Clone for LocalFsStore

Source§

fn clone(&self) -> LocalFsStore

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LocalFsStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl EnvironmentMutations for LocalFsStore

Source§

fn create_environment( &self, env_id: &EnvId, name: String, host_config: EnvironmentHostConfig, ) -> Result<Environment, StoreError>

Source§

fn update_environment( &self, env_id: &EnvId, patch: UpdateEnvironmentPayload, ) -> Result<Environment, StoreError>

Source§

fn load_environment(&self, env_id: &EnvId) -> Result<Environment, StoreError>

Reads the persisted env via EnvironmentStore::load — the trait’s one read verb, surfaced here so &dyn EnvironmentMutations callers (the remote dispatch) can evaluate client-side preconditions.

Source§

fn trust_root_is_seeded(&self, env_id: &EnvId) -> Result<bool, StoreError>

A seeded env has the trust-root file present — the seed/add paths always write ≥1 key, mirroring the tr_path.exists() check in LocalFsStore::seed_trust_root_if_absent.

Source§

fn migrate_merge_bindings( &self, target_env_id: &EnvId, payload: MigrateMergePayload, ) -> Result<(Vec<String>, Vec<String>), StoreError>

Source§

fn stage_revision( &self, env_id: &EnvId, payload: StageRevisionPayload, idempotency_key: IdempotencyKey, ) -> Result<Revision, StoreError>

Source§

fn warm_revision( &self, env_id: &EnvId, payload: WarmRevisionPayload, idempotency_key: IdempotencyKey, ) -> Result<RevisionTransitionOutcome, StoreError>

Source§

fn drain_revision( &self, env_id: &EnvId, revision_id: RevisionId, idempotency_key: IdempotencyKey, ) -> Result<RevisionTransitionOutcome, StoreError>

Source§

fn archive_revision( &self, env_id: &EnvId, revision_id: RevisionId, idempotency_key: IdempotencyKey, ) -> Result<RevisionTransitionOutcome, StoreError>

Source§

fn add_bundle( &self, env_id: &EnvId, payload: AddBundlePayload, idempotency_key: IdempotencyKey, ) -> Result<BundleDeployment, StoreError>

Source§

fn update_bundle( &self, env_id: &EnvId, payload: UpdateBundlePayload, idempotency_key: IdempotencyKey, ) -> Result<BundleDeployment, StoreError>

Source§

fn remove_bundle( &self, env_id: &EnvId, deployment_id: DeploymentId, idempotency_key: IdempotencyKey, ) -> Result<RemoveBundleOutcome, StoreError>

Source§

fn add_pack_binding( &self, env_id: &EnvId, binding: EnvPackBinding, idempotency_key: IdempotencyKey, ) -> Result<EnvPackBinding, StoreError>

Source§

fn update_pack_binding( &self, env_id: &EnvId, slot: CapabilitySlot, binding: EnvPackBinding, idempotency_key: IdempotencyKey, ) -> Result<(EnvPackBinding, u64), StoreError>

Source§

fn remove_pack_binding( &self, env_id: &EnvId, slot: CapabilitySlot, idempotency_key: IdempotencyKey, ) -> Result<(EnvPackBinding, u64), StoreError>

Source§

fn rollback_pack_binding( &self, env_id: &EnvId, slot: CapabilitySlot, idempotency_key: IdempotencyKey, ) -> Result<(EnvPackBinding, u64), StoreError>

Source§

fn add_extension_binding( &self, env_id: &EnvId, binding: ExtensionBinding, idempotency_key: IdempotencyKey, ) -> Result<ExtensionBinding, StoreError>

Source§

fn update_extension_binding( &self, env_id: &EnvId, key: ExtensionKey, binding: ExtensionBinding, idempotency_key: IdempotencyKey, ) -> Result<(ExtensionBinding, u64), StoreError>

Source§

fn remove_extension_binding( &self, env_id: &EnvId, key: ExtensionKey, idempotency_key: IdempotencyKey, ) -> Result<(ExtensionBinding, u64), StoreError>

Source§

fn rollback_extension_binding( &self, env_id: &EnvId, key: ExtensionKey, idempotency_key: IdempotencyKey, ) -> Result<(ExtensionBinding, u64), StoreError>

Source§

fn set_traffic_split( &self, env_id: &EnvId, payload: SetTrafficSplitPayload, idempotency_key: IdempotencyKey, ) -> Result<ApplyTrafficSplitOutcome, StoreError>

Source§

fn rollback_traffic_split( &self, env_id: &EnvId, deployment_id: DeploymentId, idempotency_key: IdempotencyKey, ) -> Result<RollbackTrafficSplitOutcome, StoreError>

Source§

fn add_messaging_endpoint( &self, env_id: &EnvId, payload: AddMessagingEndpointPayload, idempotency_key: IdempotencyKey, ) -> Result<MessagingEndpoint, StoreError>

Source§

fn set_messaging_welcome_flow( &self, env_id: &EnvId, payload: SetMessagingWelcomeFlowPayload, idempotency_key: IdempotencyKey, ) -> Result<MessagingEndpoint, StoreError>

Source§

fn remove_messaging_endpoint( &self, env_id: &EnvId, endpoint_id: MessagingEndpointId, ) -> Result<MessagingEndpointId, StoreError>

Source§

fn rotate_messaging_webhook_secret( &self, env_id: &EnvId, endpoint_id: MessagingEndpointId, updated_by: String, idempotency_key: IdempotencyKey, ) -> Result<MessagingEndpoint, StoreError>

Source§

fn bootstrap_trust_root( &self, env_id: &EnvId, ) -> Result<TrustRootSeed, StoreError>

Source§

fn seed_trust_root_if_absent( &self, env_id: &EnvId, ) -> Result<Option<TrustRootSeed>, StoreError>

Source§

fn add_trusted_key( &self, env_id: &EnvId, key_id: String, public_key_pem: String, idempotency_key: IdempotencyKey, ) -> Result<TrustRootAddOutcome, StoreError>

Source§

fn remove_trusted_key( &self, env_id: &EnvId, key_id: String, idempotency_key: IdempotencyKey, ) -> Result<TrustRootRemoveOutcome, StoreError>

Source§

impl EnvironmentReads for LocalFsStore

Source§

fn list_env_ids(&self) -> Result<Vec<EnvId>, StoreError>

All environment ids known to the store, sorted.
Source§

fn env_exists(&self, env_id: &EnvId) -> Result<bool, StoreError>

Whether env_id exists.
Source§

fn load_env(&self, env_id: &EnvId) -> Result<Environment, StoreError>

Load the environment document.
Source§

fn read_runtime( &self, env_id: &EnvId, ) -> Result<Option<EnvironmentRuntime>, StoreError>

Load the runtime host-config sidecar, or None when none has been written. Both backends read it (the HTTP store via GET /environments/{env_id}/runtime), so None means genuinely absent.
Source§

impl EnvironmentStore for LocalFsStore

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ServiceExt for T

Source§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Follow redirect resposes using the Standard policy. Read more
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more