1
0
Fork 0
mirror of https://github.com/imjasonh/git-k8s synced 2026-07-18 15:05:45 +00:00

Implement PVC-backed Git workspace cache (design-pvc-workspace.md)

Add pkg/workspace.Manager that provides Acquire/Release semantics for Git
repos. When GIT_CACHE_DIR is set and a GitRepository has spec.cache.enabled,
controllers use on-disk bare clones with incremental fetch; otherwise they
fall back to the existing in-memory clone behavior.

Key changes:
- New pkg/workspace package with Manager, Workspace, GC, Deepen, and
  context-based injection (WithManager/GetManager)
- GitRepository API gains spec.cache (CacheConfig) and status.cache
  (CacheStatus) with deepcopy and CRD schema updates
- Push, sync, and resolver reconcilers now use workspace.Acquire/Release
  instead of inline memory.NewStorage + git.CloneContext
- Shallow clone by default; sync/resolver deepen as needed for merge-base
- New Prometheus metrics: workspace_acquire_duration_seconds,
  workspace_cache_hit_total, workspace_cache_miss_total
- Deployment manifests include commented-out PVC configuration
- Comprehensive unit tests for workspace package (21 tests)
- E2E tests for cache-free and cache-enabled push flows

https://claude.ai/code/session_01NULGxaCLPMT1yDVEAsffc5
This commit is contained in:
Claude 2026-03-17 15:20:57 +00:00
parent 831132d826
commit a1a4142976
No known key found for this signature in database
22 changed files with 1374 additions and 69 deletions

View file

@ -35,6 +35,18 @@ type GitRepositorySpec struct {
// If unset, the controller's default poll interval is used.
// +optional
PollInterval *metav1.Duration `json:"pollInterval,omitempty"`
// Cache configures on-disk caching for this repository.
// When enabled, controllers with a PVC mounted will use a persistent
// bare clone instead of cloning into memory each time.
// +optional
Cache *CacheConfig `json:"cache,omitempty"`
}
// CacheConfig configures on-disk caching for a GitRepository.
type CacheConfig struct {
// Enabled indicates whether on-disk caching should be used for this repo.
Enabled bool `json:"enabled"`
}
// GitAuth contains authentication details for accessing a Git repository.
@ -58,6 +70,25 @@ type GitRepositoryStatus struct {
// LastFetchTime is the timestamp of the last successful fetch.
// +optional
LastFetchTime *metav1.Time `json:"lastFetchTime,omitempty"`
// Cache contains cache health information.
// +optional
Cache *CacheStatus `json:"cache,omitempty"`
}
// CacheStatus reports the current state of the on-disk cache for a repository.
type CacheStatus struct {
// LastCloneTime is the timestamp of the initial clone to disk.
// +optional
LastCloneTime *metav1.Time `json:"lastCloneTime,omitempty"`
// LastFetchTime is the timestamp of the last git fetch on the cached repo.
// +optional
LastFetchTime *metav1.Time `json:"lastFetchTime,omitempty"`
// SizeBytes is the approximate size of the cached repo on disk.
// +optional
SizeBytes int64 `json:"sizeBytes,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View file

@ -10,6 +10,44 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CacheConfig) DeepCopyInto(out *CacheConfig) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CacheConfig.
func (in *CacheConfig) DeepCopy() *CacheConfig {
if in == nil {
return nil
}
out := new(CacheConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CacheStatus) DeepCopyInto(out *CacheStatus) {
*out = *in
if in.LastCloneTime != nil {
in, out := &in.LastCloneTime, &out.LastCloneTime
*out = (*in).DeepCopy()
}
if in.LastFetchTime != nil {
in, out := &in.LastFetchTime, &out.LastFetchTime
*out = (*in).DeepCopy()
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CacheStatus.
func (in *CacheStatus) DeepCopy() *CacheStatus {
if in == nil {
return nil
}
out := new(CacheStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GitAuth) DeepCopyInto(out *GitAuth) {
*out = *in
@ -85,6 +123,11 @@ func (in *GitRepositorySpec) DeepCopyInto(out *GitRepositorySpec) {
*out = new(metav1.Duration)
**out = **in
}
if in.Cache != nil {
in, out := &in.Cache, &out.Cache
*out = new(CacheConfig)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitRepositorySpec.
@ -105,6 +148,11 @@ func (in *GitRepositoryStatus) DeepCopyInto(out *GitRepositoryStatus) {
in, out := &in.LastFetchTime, &out.LastFetchTime
*out = (*in).DeepCopy()
}
if in.Cache != nil {
in, out := &in.Cache, &out.Cache
*out = new(CacheStatus)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitRepositoryStatus.