git_cache_proxy/config.rs
1// SPDX-License-Identifier: Apache-2.0
2//! Command-line / environment configuration.
3
4use std::path::PathBuf;
5
6use clap::{Parser, ValueEnum};
7
8/// Log output format.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
10pub enum LogFormat {
11 /// Human-readable single-line text.
12 Text,
13 /// One JSON object per line (for log shippers).
14 Json,
15}
16
17#[derive(Parser, Debug, Clone)]
18#[command(
19 name = "git-cache-proxy",
20 version,
21 about = "Read-only caching proxy for Git repositories"
22)]
23pub struct Config {
24 /// Address to bind the HTTP server to.
25 #[arg(long, env = "GITCACHEPROXY_BIND", default_value = "0.0.0.0:8080")]
26 pub bind: String,
27
28 /// Directory holding the bare mirror caches.
29 #[arg(
30 long,
31 env = "GITCACHEPROXY_CACHE_ROOT",
32 default_value = "/var/cache/git-cache-proxy"
33 )]
34 pub cache_root: PathBuf,
35
36 /// Upstream git base URL, e.g. `https://git.example.com`. Requested repo
37 /// paths are appended to this to locate the origin.
38 #[arg(long, env = "GITCACHEPROXY_UPSTREAM")]
39 pub upstream: String,
40
41 /// Optional header injected on upstream clone/fetch for auth, e.g.
42 /// `Authorization: Bearer <token>`. Read from the environment so the token
43 /// never appears in argv (and it is passed to git via env, not `-c`, so it
44 /// stays out of the child's argv too).
45 #[arg(
46 long,
47 env = "GITCACHEPROXY_UPSTREAM_AUTH_HEADER",
48 hide_env_values = true
49 )]
50 pub upstream_auth_header: Option<String>,
51
52 /// Optional bearer token clients must present (`Authorization: Bearer ...`).
53 /// Unset = serve anonymously (intended for a network-restricted deployment).
54 #[arg(long, env = "GITCACHEPROXY_SERVE_TOKEN", hide_env_values = true)]
55 pub serve_token: Option<String>,
56
57 /// Skip the upstream fetch on `info/refs` if the mirror was refreshed within
58 /// this many seconds. Coalesces bursts of clones for the same repo. `0` =
59 /// always fetch (freshest, more upstream load).
60 #[arg(long, env = "GITCACHEPROXY_FETCH_TTL_SECONDS", default_value_t = 10)]
61 pub fetch_ttl_seconds: u64,
62
63 /// Maximum number of requests handled concurrently, shared across all
64 /// connections. Excess requests queue until a slot frees. This bounds the
65 /// concurrent upstream clone/fetch work a burst can trigger (the slot is held
66 /// for the handler, then released before the packfile streams, so it caps
67 /// setup rather than in-flight streaming). `0` = unlimited. Complementary to
68 /// any ingress-level rate limiting.
69 #[arg(
70 long,
71 env = "GITCACHEPROXY_MAX_CONCURRENT_REQUESTS",
72 default_value_t = 64
73 )]
74 pub max_concurrent_requests: usize,
75
76 /// Maximum size, in MiB, of a decoded `git-upload-pack` request body (the
77 /// client's want/have negotiation). Bounds in-memory buffering and defuses a
78 /// gzip decompression bomb - a small compressed body can expand ~1000x. This
79 /// caps only the negotiation request, never the streamed packfile response,
80 /// so raising it is rarely needed even for very large repositories.
81 #[arg(long, env = "GITCACHEPROXY_MAX_DECODED_BODY_MB", default_value_t = 512)]
82 pub max_decoded_body_mb: u64,
83
84 /// Maximum total size, in MiB, of the on-disk mirror cache. When a clone or
85 /// fetch pushes the total over this, least-recently-used idle mirrors are
86 /// evicted in the background until it is back under; an evicted mirror is
87 /// transparently re-cloned on its next request. `0` = unlimited: no eviction
88 /// and no accounting, so the cache grows without bound (the default).
89 #[arg(long, env = "GITCACHEPROXY_CACHE_MAX_MB", default_value_t = 0)]
90 pub cache_max_mb: u64,
91
92 /// Path to the git binary.
93 #[arg(long, env = "GITCACHEPROXY_GIT_BINARY", default_value = "git")]
94 pub git_binary: String,
95
96 /// Log filter directive (e.g. `info`, `git_cache_proxy=debug,tower=warn`).
97 /// Overridden by the `RUST_LOG` environment variable when set.
98 #[arg(long, env = "GITCACHEPROXY_LOG", default_value = "info")]
99 pub log: String,
100
101 /// Log output format.
102 #[arg(
103 long,
104 value_enum,
105 env = "GITCACHEPROXY_LOG_FORMAT",
106 default_value = "text"
107 )]
108 pub log_format: LogFormat,
109}