Documentation
¶
Overview ¶
Package git implements a protocol-aware Git caching proxy strategy.
Index ¶
- Constants
- Variables
- func ExtractRepoPath(pathValue string) string
- func Register(r *strategy.Registry, scheduler jobscheduler.Provider, ...)
- func RequestIsClone(pathValue string, r *http.Request) (bool, error)
- func SpoolKeyForRequest(pathValue string, r *http.Request) (string, error)
- type Config
- type EnsureRefsRequest
- type EnsureRefsResponse
- type RepoCount
- type RepoCounts
- type RepoSpools
- type ResponseSpool
- func (rs *ResponseSpool) CaptureHeader(status int, header http.Header)
- func (rs *ResponseSpool) Failed() bool
- func (rs *ResponseSpool) MarkComplete()
- func (rs *ResponseSpool) MarkError(err error)
- func (rs *ResponseSpool) ServeTo(w http.ResponseWriter) error
- func (rs *ResponseSpool) WaitForReaders()
- func (rs *ResponseSpool) Write(data []byte) error
- func (rs *ResponseSpool) Written() int64
- type SpoolTeeWriter
- type Strategy
Constants ¶
const EnsureRefsPath = "/ensure-refs"
EnsureRefsPath is the URL suffix for the ref-freshness endpoint. Clients POST to /git/{host}/{repo}/ensure-refs to force cachew to ensure the local mirror contains the listed refs before they fetch.
Variables ¶
var ErrSpoolFailed = errors.New("spool failed before response started")
ErrSpoolFailed is returned by ServeTo when the spool failed before any headers were written to the client, allowing the caller to fall back to upstream.
Functions ¶
func ExtractRepoPath ¶
func Register ¶
func Register(r *strategy.Registry, scheduler jobscheduler.Provider, cloneManagerProvider gitclone.ManagerProvider, tokenManagerProvider githubapp.TokenManagerProvider)
func RequestIsClone ¶
RequestIsClone reports whether r is an initial clone of a Git repo.
Detection: POST /git-upload-pack whose pkt-line body contains no "have <oid>" line. v2 command=ls-refs (discovery) is also rejected. The body is buffered and replayed via io.NopCloser.
func SpoolKeyForRequest ¶
SpoolKeyForRequest returns the spool key for a request, or empty string if the request is not spoolable. For POST requests, the body is hashed to differentiate protocol v2 commands (e.g. ls-refs vs fetch) that share the same URL. The request body is buffered and replaced so it can still be read by the caller.
Types ¶
type Config ¶
type Config struct {
SnapshotInterval time.Duration `` /* 127-byte string literal not displayed */
MirrorSnapshotInterval time.Duration `` /* 159-byte string literal not displayed */
RepackInterval time.Duration `hcl:"repack-interval,optional" help:"How often to run full repack. 0 disables." default:"0"`
ZstdThreads int `` /* 248-byte string literal not displayed */
BundleCacheTTL time.Duration `hcl:"bundle-cache-ttl,optional" help:"TTL of cached server-side git bundles." default:"2h"`
}
type EnsureRefsRequest ¶
type EnsureRefsRequest struct {
Refs map[string]string `json:"refs,omitempty"`
Commits []string `json:"commits,omitempty"`
}
EnsureRefsRequest is the JSON request body for POST .../ensure-refs. At least one of Refs or Commits must be non-empty.
Refs maps each required ref (e.g. "refs/heads/main") to the expected SHA. An empty SHA means "require the ref to exist, at any SHA".
Commits lists individual commit SHAs that must exist in the mirror's object database, regardless of which ref points at them.
type EnsureRefsResponse ¶
type EnsureRefsResponse struct {
Refs map[string]string `json:"refs,omitempty"`
MissingCommits []string `json:"missing_commits,omitempty"`
Fetched bool `json:"fetched"`
}
EnsureRefsResponse is the JSON response body for POST .../ensure-refs.
Refs contains the resolved local SHA for each requested ref (empty if the ref is still missing after the fetch). MissingCommits lists the requested commits that are still absent from the local object database after the fetch. Fetched reports whether an upstream fetch was performed.
type RepoCounts ¶
type RepoCounts struct {
// contains filtered or unexported fields
}
RepoCounts tracks per-repository clone counts in a daily-bucketed IntMap. All methods are nil-safe.
func NewRepoCounts ¶
func NewRepoCounts(ns *metadatadb.Namespace) *RepoCounts
NewRepoCounts returns nil if ns is nil so callers don't need a separate "no metadata configured" code path.
func (*RepoCounts) IncrementClone ¶
func (r *RepoCounts) IncrementClone(upstreamURL string)
IncrementClone bumps today's bucket (UTC) for upstreamURL.
func (*RepoCounts) Reap ¶
func (r *RepoCounts) Reap() int
Reap deletes buckets older than the retention window and any malformed keys, returning the number of entries deleted.
func (*RepoCounts) TopRepos ¶
func (r *RepoCounts) TopRepos(windowDays, limit int) []RepoCount
TopRepos aggregates buckets over the last windowDays days (UTC) and returns rows sorted by count descending then repo name ascending. windowDays <= 0 means no window; limit <= 0 means no truncation.
type RepoSpools ¶
type RepoSpools struct {
// contains filtered or unexported fields
}
RepoSpools manages all response spools for a single repository.
func NewRepoSpools ¶
func NewRepoSpools(dir string) *RepoSpools
func (*RepoSpools) Close ¶
func (rp *RepoSpools) Close() error
Close marks the repo spools as closed, waits for all readers to finish, and removes spool files from disk.
func (*RepoSpools) GetOrCreate ¶
func (rp *RepoSpools) GetOrCreate(key string) (spool *ResponseSpool, isWriter bool, err error)
GetOrCreate returns an existing spool for the key, or creates a new one. isWriter is true if the caller created the spool and should act as the writer.
type ResponseSpool ¶
type ResponseSpool struct {
// contains filtered or unexported fields
}
ResponseSpool captures a single HTTP response (headers + body) to a file on disk, allowing one writer and multiple concurrent readers. Readers follow the writer, blocking when caught up until the write completes.
func NewResponseSpool ¶
func NewResponseSpool(filePath string) (*ResponseSpool, error)
func (*ResponseSpool) CaptureHeader ¶
func (rs *ResponseSpool) CaptureHeader(status int, header http.Header)
func (*ResponseSpool) Failed ¶
func (rs *ResponseSpool) Failed() bool
func (*ResponseSpool) MarkComplete ¶
func (rs *ResponseSpool) MarkComplete()
func (*ResponseSpool) MarkError ¶
func (rs *ResponseSpool) MarkError(err error)
func (*ResponseSpool) ServeTo ¶
func (rs *ResponseSpool) ServeTo(w http.ResponseWriter) error
ServeTo streams the spooled response to w, blocking when caught up to the writer.
func (*ResponseSpool) WaitForReaders ¶
func (rs *ResponseSpool) WaitForReaders()
WaitForReaders blocks until all active spool readers have finished.
func (*ResponseSpool) Write ¶
func (rs *ResponseSpool) Write(data []byte) error
func (*ResponseSpool) Written ¶
func (rs *ResponseSpool) Written() int64
Written returns the total number of bytes written to the spool.
type SpoolTeeWriter ¶
type SpoolTeeWriter struct {
// contains filtered or unexported fields
}
SpoolTeeWriter wraps an http.ResponseWriter to capture the response into a spool while simultaneously streaming it to the original client.
func NewSpoolTeeWriter ¶
func NewSpoolTeeWriter(inner http.ResponseWriter, spool *ResponseSpool) *SpoolTeeWriter
NewSpoolTeeWriter creates a new SpoolTeeWriter that tees writes to both the inner ResponseWriter and the given spool.
func (*SpoolTeeWriter) Flush ¶
func (w *SpoolTeeWriter) Flush()
func (*SpoolTeeWriter) Header ¶
func (w *SpoolTeeWriter) Header() http.Header
func (*SpoolTeeWriter) WriteHeader ¶
func (w *SpoolTeeWriter) WriteHeader(code int)
type Strategy ¶
type Strategy struct {
// contains filtered or unexported fields
}
func New ¶
func New( ctx context.Context, config Config, schedulerProvider jobscheduler.Provider, cache cache.Cache, mux strategy.Mux, cloneManagerProvider gitclone.ManagerProvider, tokenManagerProvider githubapp.TokenManagerProvider, ) (*Strategy, error)
func (*Strategy) SetHTTPTransport ¶
func (s *Strategy) SetHTTPTransport(t http.RoundTripper)
SetHTTPTransport overrides the HTTP transport used for upstream requests. This is intended for testing.
func (*Strategy) SetMetadataStore ¶
func (s *Strategy) SetMetadataStore(store *metadatadb.Store)
SetMetadataStore enables the per-repo clone histogram and schedules its daily reaper. Called by config.Load after the metadata backend is built.