Overview
Add support for mirroring complete Git repositories. This enables:
- Repository backup: Secure copy with full history in case of force-push or deletion
- Air-gapped development: Mirror source repositories for offline access
- Compliance: Archival of dependencies with full Git history
Use Case
Problem 1: Force-push protection
- Upstream maintainers can force-push and rewrite history
- Critical dependencies can disappear (left-pad incident)
- Need immutable backup of repository state
Problem 2: Air-gapped source access
- Development environments without internet access
- Need full Git repos including all branches/tags/history
- Not just release tarballs - need actual Git repository
Examples:
Proposed Implementation
Plugin Type: git-mirror
Uses tarball approach to fit into content-addressed storage model.
Architecture
Key Concept: Git repositories are archived as tarballs and stored in the pool.
Sync:
git clone --mirror → tar.gz → SHA256 → pool
Publishing:
Extract tarball → /var/www/repos/repo-name/latest/
No hardlinks possible (directories, not files), but deduplication still works via tarball checksums.
Example Configuration
repositories:
Sync Workflow
-
Clone or update mirror:
- git clone --mirror (initial)
- git fetch --all --prune (update)
-
Create tarball:
- tar czf repo-mirror.tar.gz -C /tmp repo.git/
-
Calculate SHA256
-
Store in pool if not exists:
- /var/lib/chantal/pool/ab/cd/abcd1234...tar.gz
-
Create ContentItem in database
Deduplication
Works automatically via tarball SHA256.
Scenario: No new commits since last sync
- git fetch --all --prune (no changes)
- tar czf creates identical tarball
- Same SHA256 → already in pool, skip storage
Deduplication confirmed!
Note: Tar archives are deterministic if using --sort=name --mtime flags.
Publishing
Cannot use hardlinks (tarball contains directory structure).
Publishing workflow:
- Extract tarball to staging directory
- Atomic swap via symlink
- Run git update-server-info for HTTP access
Published structure:
/var/www/repos/kubernetes-source/
├── latest/kubernetes.git/
└── snapshots/2025-01/kubernetes.git/
Git Access Methods
HTTP (dumb protocol) - simplest:
HTTP (smart protocol):
- Requires git-http-backend CGI setup
- Faster for large repos
SSH:
- Requires SSH server with git-shell
- Most secure option
Database Schema
GitMirror table:
- repository_id, last_sync, head_commit, branch_count, tag_count
GitMirrorSnapshot table:
- mirror_id, content_item_id, name, created_at, head_commit
- refs_snapshot (JSON): refs/heads/main, refs/tags/v1.28.0, etc.
Snapshots
Snapshot = Tarball reference + metadata
Benefits:
- Points to tarball in pool (no duplication)
- Stores Git metadata (commits, refs)
- Can be published to separate directory
Storage Optimization
Problem: Large repositories (Linux Kernel: 4 GB bare repo)
Mitigations:
- Selective mirroring (only specific branches/tags)
- Shallow clones (optional, not a true mirror)
- Compression testing (tar vs tar.gz for Git objects)
Benefits
- Deduplication works (unchanged repo → same tarball SHA256)
- Snapshots work (tarball references + metadata)
- Fits into content-addressed storage (tarballs are files)
- Force-push protection (immutable snapshots)
- Simple implementation (git clone + tar + extract)
Limitations
- No hardlinks (must extract tarball for publishing)
- Large repos are large (Linux Kernel: 4 GB)
- Publishing not instant (extraction takes time)
- Deterministic tarballs need --sort=name --mtime flags
Alternative Considered
Native Git pool (store repos directly without tarball):
- Rejected: Does not fit content-addressed model
- No SHA256-based deduplication
- Snapshots would require full repo copies
- Tarball approach is simpler
Implementation Steps
- Create src/chantal/plugins/git_mirror_sync.py
- Implement git clone --mirror wrapper
- Implement tarball creation (deterministic tar)
- Store tarball in content-addressed pool
- Add database models (GitMirror, GitMirrorSnapshot)
- Implement publishing (extract tarball atomically)
- Add git update-server-info for HTTP access
- Add chantal repo sync --type git-mirror
- Add chantal content list --type git-mirror
- Documentation (HTTP/SSH access setup)
- Example configurations in examples/git/
Example Repositories to Mirror
Kubernetes Ecosystem:
- kubernetes/kubernetes
- helm/helm
- etcd-io/etcd
Build Dependencies:
Internal Dependencies:
- GitLab/GitHub Enterprise repos
Future Enhancements
- Support for Git LFS (large file storage)
- Support for submodules
- Incremental tarball updates (only changed objects)
- Git GC optimization before tarball creation
- Support for Gitea, Gogs, Bitbucket
Related
Overview
Add support for mirroring complete Git repositories. This enables:
Use Case
Problem 1: Force-push protection
Problem 2: Air-gapped source access
Examples:
Proposed Implementation
Plugin Type: git-mirror
Uses tarball approach to fit into content-addressed storage model.
Architecture
Key Concept: Git repositories are archived as tarballs and stored in the pool.
Sync:
git clone --mirror → tar.gz → SHA256 → pool
Publishing:
Extract tarball → /var/www/repos/repo-name/latest/
No hardlinks possible (directories, not files), but deduplication still works via tarball checksums.
Example Configuration
repositories:
id: kubernetes-source
type: git-mirror
feed: https://github.com/kubernetes/kubernetes
enabled: true
git:
sync_mode: mirror # All branches and tags
id: helm-source
type: git-mirror
feed: https://github.com/helm/helm
git:
sync_mode: selective
branches: [main, release-3.14, release-3.13]
tags_pattern: "^v3\.(1[34])\." # v3.13.x, v3.14.x
Sync Workflow
Clone or update mirror:
Create tarball:
Calculate SHA256
Store in pool if not exists:
Create ContentItem in database
Deduplication
Works automatically via tarball SHA256.
Scenario: No new commits since last sync
Deduplication confirmed!
Note: Tar archives are deterministic if using --sort=name --mtime flags.
Publishing
Cannot use hardlinks (tarball contains directory structure).
Publishing workflow:
Published structure:
/var/www/repos/kubernetes-source/
├── latest/kubernetes.git/
└── snapshots/2025-01/kubernetes.git/
Git Access Methods
HTTP (dumb protocol) - simplest:
HTTP (smart protocol):
SSH:
Database Schema
GitMirror table:
GitMirrorSnapshot table:
Snapshots
Snapshot = Tarball reference + metadata
Benefits:
Storage Optimization
Problem: Large repositories (Linux Kernel: 4 GB bare repo)
Mitigations:
Benefits
Limitations
Alternative Considered
Native Git pool (store repos directly without tarball):
Implementation Steps
Example Repositories to Mirror
Kubernetes Ecosystem:
Build Dependencies:
Internal Dependencies:
Future Enhancements
Related