1#![deny(unsafe_code)]
2#![allow(
3 clippy::indexing_slicing,
4 clippy::missing_errors_doc,
5 clippy::missing_panics_doc,
6 clippy::let_underscore_must_use
7)]
8#![cfg_attr(
9 test,
10 allow(
11 clippy::unwrap_used,
12 clippy::expect_used,
13 clippy::arithmetic_side_effects,
14 clippy::shadow_unrelated,
15 clippy::format_push_string
16 )
17)]
18
19pub mod app;
45mod auth;
46mod backend;
47mod backup;
48mod chunk_store;
49mod clock;
50mod config;
51mod database_migration;
52pub mod download_stream;
53mod error;
54mod fsck;
55mod fuzz;
56mod ingest_bench;
57mod jwks_provider;
58mod lifecycle_repair;
59mod local_backend;
60mod local_fs;
61mod local_path;
62pub mod metrics;
63mod model;
64mod object_store;
65mod oidc_provider;
66mod ops_record_store;
67mod overflow;
68mod postgres_backend;
69mod protocol_support;
70mod provider;
71mod provider_events;
72mod rebuild;
73mod reconstruction_cache;
74mod record_store;
75mod repository_scope_path;
76mod runtime_check;
77mod server_frontend;
78mod server_role;
79mod storage_migration;
80pub mod test_fixtures;
81pub mod test_invariant_error;
82
83pub use app::ProtocolMetrics;
84pub use app::{
85 AppState, MAX_PROVIDER_NAME_BYTES, MAX_PROVIDER_SUBJECT_BYTES,
86 MAX_PROVIDER_TOKEN_REQUEST_BODY_BYTES, MAX_PROVIDER_WEBHOOK_BODY_BYTES,
87 acquire_chunk_transfer_permit, full_byte_stream_response,
88};
89pub use backend::{
90 BenchmarkBackend, ServerBackend, clear_repository_reference_probe_filter,
91 lock_repository_reference_probe_test, repository_reference_probe_count,
92 reset_repository_reference_probe_count_for_hash,
93};
94pub use download_stream::{STREAM_READ_BUFFER_BYTES, ServerByteStream};
95pub use local_backend::chunk_hash;
96pub use object_store::ServerObjectStore;
97pub use oci_adapter::{oci_blob_key, oci_manifest_key, oci_manifest_media_type_key};
98pub use protocol_support::shared_sha256_object_key;
99pub use reconstruction_cache::ReconstructionCacheService;
100pub(crate) use shardline_oci_adapter as oci_adapter;
101pub use shardline_protocol_adapters::{BazelCacheKind, bazel_cache_object_key, lfs_object_key};
102pub use transfer_limiter::TransferLimiter;
103#[cfg(test)]
104mod gc_tests;
105mod transfer_limiter;
106mod upload_ingest;
107mod validation;
108pub(crate) use shardline_xet_adapter as xet_adapter;
109
110pub use app::{serve, serve_with_listener};
111pub use backup::{BackupManifestReport, write_backup_manifest};
112pub use config::{
113 AuthProviderKind, ObjectStorageAdapter, ServerConfig, ServerConfigError, ShardMetadataLimits,
114};
115pub use database_migration::{
116 DatabaseMigration, DatabaseMigrationCommand, DatabaseMigrationError, DatabaseMigrationOptions,
117 DatabaseMigrationReport, DatabaseMigrationStatusEntry, apply_database_migrations,
118 bundled_database_migrations, run_database_migration,
119};
120pub use error::ServerError;
121pub(crate) use error::{InvalidReconstructionResponseError, InvalidSerializedShardError};
122pub use fsck::{
123 FsckIssueDetail, FsckIssueKind, FsckReconstructionPlanDetail, LocalFsckIssue,
124 LocalFsckIssueKind, LocalFsckReport, ProviderRepositoryStateTimestampField, run_fsck,
125 run_local_fsck,
126};
127pub use fuzz::{
128 FuzzBazelHttpFrontendSummary, FuzzLfsFrontendSummary, FuzzLifecycleRepairSummary,
129 FuzzOciFrontendSummary, FuzzProtocolFrontendSummary, FuzzReconstructionResponseSummary,
130 FuzzRetainedShardSummary, FuzzValidatedXorbSummary, fuzz_bazel_http_frontend_summary,
131 fuzz_lfs_frontend_summary, fuzz_lifecycle_repair_summary, fuzz_normalize_and_validate_xorb,
132 fuzz_oci_frontend_summary, fuzz_protocol_frontend_summary,
133 fuzz_reconstruction_response_summary, fuzz_retained_shard_chunk_hashes,
134};
135pub use gc::{
136 DEFAULT_LOCAL_GC_RETENTION_SECONDS, LocalGcDiagnostics, LocalGcOptions, LocalGcReport,
137};
138pub use ingest_bench::ingest_without_storage_with_parallelism;
139pub use lifecycle_repair::{
140 DEFAULT_WEBHOOK_DELIVERY_RETENTION_SECONDS, LifecycleRepairOptions, LifecycleRepairReport,
141 run_lifecycle_repair, run_local_lifecycle_repair,
142};
143pub use local_backend::LocalBackend;
144pub use model::{
145 GitLfsAuthenticateResponse, HealthResponse, ProviderTokenIssueRequest,
146 ProviderTokenIssueResponse, ProviderWebhookResponse, ReadyResponse, ServerStatsResponse,
147 XetCasTokenResponse,
148};
149pub(crate) use postgres_backend::PostgresBackend;
150pub use rebuild::{
151 IndexRebuildIssueDetail, IndexRebuildReconstructionPlanDetail, LocalIndexRebuildIssue,
152 LocalIndexRebuildIssueKind, LocalIndexRebuildReport, run_index_rebuild,
153 run_local_index_rebuild,
154};
155pub use reconstruction_cache::{
156 ReconstructionCacheBenchReport, benchmark_memory_reconstruction_cache,
157};
158pub use runtime_check::{ConfigCheckReport, run_config_check};
159pub use server_frontend::{ServerFrontend, ServerFrontendParseError};
160pub use server_role::{ServerRole, ServerRoleParseError};
161pub(crate) use shardline_gc as gc;
162pub(crate) use shardline_protocol_adapters::{
163 LFS_CONTENT_TYPE, LfsBatchRequest, LfsBatchResponse, LfsObjectError, LfsObjectResponse,
164};
165pub(crate) use shardline_xet_adapter::ShardUploadResponse;
166pub use storage_migration::{
167 StorageMigrationEndpoint, StorageMigrationOptions, StorageMigrationReport,
168 run_storage_migration,
169};
170pub use xet_adapter::{
171 BatchReconstructionResponse, FileReconstructionResponse, FileReconstructionV2Response,
172 XorbUploadResponse, decode_serialized_xorb_chunks, try_for_each_serialized_xorb_chunk,
173 validate_serialized_xorb,
174};
175
176use object_store::object_store_from_config;
177use postgres_backend::connect_postgres_metadata_pool;
178use shardline_index::{LocalIndexStore, LocalRecordStore, PostgresIndexStore, PostgresRecordStore};
179
180pub async fn run_gc(
187 config: ServerConfig,
188 options: gc::LocalGcOptions,
189) -> Result<gc::LocalGcReport, error::ServerError> {
190 Ok(run_gc_diagnostics(config, options).await?.report)
191}
192
193pub async fn run_gc_diagnostics(
200 config: ServerConfig,
201 options: gc::LocalGcOptions,
202) -> Result<gc::LocalGcDiagnostics, error::ServerError> {
203 let object_store = object_store_from_config(&config)?;
204 if let Some(index_postgres_url) = config.index_postgres_url() {
205 let pool = connect_postgres_metadata_pool(index_postgres_url, 4)?;
206 let index_store = PostgresIndexStore::new(pool.clone());
207 let record_store = PostgresRecordStore::new(pool);
208 return gc::run_gc_with_stores(
209 &record_store,
210 &index_store,
211 &object_store,
212 config.server_frontends(),
213 options,
214 )
215 .await
216 .map_err(Into::into);
217 }
218
219 let index_store = LocalIndexStore::open(config.root_dir().to_path_buf());
220 let record_store = LocalRecordStore::open(config.root_dir().to_path_buf());
221 gc::run_gc_with_stores(
222 &record_store,
223 &index_store,
224 &object_store,
225 config.server_frontends(),
226 options,
227 )
228 .await
229 .map_err(Into::into)
230}