Skip to main content

WireConfig

Struct WireConfig 

Source
pub struct WireConfig {
    pub upload: Config,
    pub receive: Config,
    pub lfs: Limits,
    pub attest_objects: bool,
}
Expand description

What gunnar-wire is configured with, for both directions.

gunnar-wire has had these knobs since it was written, and a with_config on both state machines to receive them. Nothing ever called either: this module said UploadPack::new(…) and ReceivePack::new(…), so every deployment ran on Config::default() and an operator could not decline filter — the one capability the type’s own doc comment says is “the one capability an operator plausibly wants to decline”.

A configuration surface that cannot affect behaviour is worse than none. It reads as a control that works: an appliance that had to state it does not serve partial clones had Offered { filter: false } sitting right there, fully implemented in both protocol versions, and no way at all to reach it. So the knobs are wired rather than deleted, and this struct is the one place the two gunnar_wire::…::Config types are held (one implementation) — a second copy of agent or budget on ServeConfig is how a value ends up honoured on one direction and stubbed on the other.

Fields§

§upload: Config

What git-upload-pack serves under: offered, want_policy, budget and limits.

§receive: Config

What git-receive-pack serves under: the connectivity budget.

§lfs: Limits

What git-lfs-transfer serves under.

Held here and not beside the store for the same reason the two above are: the LFS session is a third service on this one listener, and a second home for its quota is how 8 GiB comes to be enforced by the SSH path and not by the next caller. gunnar_lfs::Session::with_limits and the three builders behind it had zero call sites outside tests/quota.rs — every deployment ran on Limits::default() and the numbers in the doc comments were not reachable from any command line.

§attest_objects: bool

Enumerate the objects each push introduced, so the push attestation can name them. On by default.

The ids are not a by-product of storing a pack — a pack entry does not carry its oid — so answering this waits for the engine’s indexer to drain, which is real latency on the push path (storage::znippy_engine::ingest has the measured multiples). Before this flag existed the enumeration happened only when a policy gate needed it, and an attestation on a repository with no gates therefore carried an empty object list that was indistinguishable from a push that introduced nothing.

Turning it off does not restore that silence: the attestation then records the reason the set is absent (new_object_oids_unknown), because an absence that renders as a value is the defect this flag was added to remove, not the behaviour it restores.

Implementations§

Source§

impl WireConfig

Source

pub fn from_serve_args(args: &ServeArgs) -> Result<Self>

The knobs an operator set on gunnar serve, translated once.

None on every flag means “the operator did not say”, which takes gunnar-wire’s default — the same convention --max-concurrent-transfers already uses. 0 is a stated value and is treated as one:

  • on the two byte ceilings it is the documented way to remove them, because Limits’ fields are Option and None means unbounded;
  • on --fetch-budget it is refused, because the walk stops when it reaches the budget, so 0 would mean a server that answers no fetch at all while reading as “no limit”. An unbounded-looking flag that silently bricks the server is the failure this whole item is about.
Source

pub fn lfs_session<'a>( &self, store: &'a dyn LfsStore, operation: Operation, ) -> Session<'a>

The one place an LFS session is built.

By construction rather than by a guard that watches two call sites agree (one implementation). The defect this closes was exactly a second construction path: Session::new(…).serve(…) in the SSH transport, with with_limits reachable only from tests/quota.rs. A test that built its own session could be green with the server on Limits::default() forever, so the test drives this and there is nothing else to drive.

Trait Implementations§

Source§

impl Clone for WireConfig

Source§

fn clone(&self) -> Self

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 WireConfig

Source§

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

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

impl Default for WireConfig

Source§

fn default() -> Self

Hand-written for one field. #[derive(Default)] would make WireConfig::attest_objects false, and the safe default here is the one that produces a complete attestation — the cheap default is the one an operator opts into, never the one they get by forgetting.

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
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> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
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> 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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<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