chantal 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chantal-1.0.0/MANIFEST.in +13 -0
- chantal-1.0.0/PKG-INFO +353 -0
- chantal-1.0.0/README.md +306 -0
- chantal-1.0.0/pyproject.toml +186 -0
- chantal-1.0.0/setup.cfg +4 -0
- chantal-1.0.0/src/chantal/__init__.py +22 -0
- chantal-1.0.0/src/chantal/cli/__init__.py +3 -0
- chantal-1.0.0/src/chantal/cli/cache_commands.py +217 -0
- chantal-1.0.0/src/chantal/cli/content_commands.py +519 -0
- chantal-1.0.0/src/chantal/cli/db_commands.py +505 -0
- chantal-1.0.0/src/chantal/cli/main.py +146 -0
- chantal-1.0.0/src/chantal/cli/pool_commands.py +449 -0
- chantal-1.0.0/src/chantal/cli/publish_commands.py +727 -0
- chantal-1.0.0/src/chantal/cli/repo_commands.py +1418 -0
- chantal-1.0.0/src/chantal/cli/snapshot_commands.py +984 -0
- chantal-1.0.0/src/chantal/cli/view_commands.py +181 -0
- chantal-1.0.0/src/chantal/core/__init__.py +38 -0
- chantal-1.0.0/src/chantal/core/cache.py +315 -0
- chantal-1.0.0/src/chantal/core/config.py +957 -0
- chantal-1.0.0/src/chantal/core/downloader.py +403 -0
- chantal-1.0.0/src/chantal/core/gpg.py +300 -0
- chantal-1.0.0/src/chantal/core/gpg_verify.py +181 -0
- chantal-1.0.0/src/chantal/core/output.py +259 -0
- chantal-1.0.0/src/chantal/core/storage.py +382 -0
- chantal-1.0.0/src/chantal/db/__init__.py +32 -0
- chantal-1.0.0/src/chantal/db/connection.py +89 -0
- chantal-1.0.0/src/chantal/db/migrations.py +219 -0
- chantal-1.0.0/src/chantal/db/models.py +518 -0
- chantal-1.0.0/src/chantal/plugins/__init__.py +13 -0
- chantal-1.0.0/src/chantal/plugins/apk/models.py +128 -0
- chantal-1.0.0/src/chantal/plugins/apk/publisher.py +297 -0
- chantal-1.0.0/src/chantal/plugins/apk/signing.py +183 -0
- chantal-1.0.0/src/chantal/plugins/apk/sync.py +531 -0
- chantal-1.0.0/src/chantal/plugins/apt/__init__.py +19 -0
- chantal-1.0.0/src/chantal/plugins/apt/gpg.py +12 -0
- chantal-1.0.0/src/chantal/plugins/apt/models.py +178 -0
- chantal-1.0.0/src/chantal/plugins/apt/parsers.py +532 -0
- chantal-1.0.0/src/chantal/plugins/apt/publisher.py +819 -0
- chantal-1.0.0/src/chantal/plugins/apt/sync.py +1260 -0
- chantal-1.0.0/src/chantal/plugins/base.py +143 -0
- chantal-1.0.0/src/chantal/plugins/helm/models.py +130 -0
- chantal-1.0.0/src/chantal/plugins/helm/publisher.py +260 -0
- chantal-1.0.0/src/chantal/plugins/helm/sync.py +507 -0
- chantal-1.0.0/src/chantal/plugins/rpm/compression.py +145 -0
- chantal-1.0.0/src/chantal/plugins/rpm/filters.py +287 -0
- chantal-1.0.0/src/chantal/plugins/rpm/models.py +49 -0
- chantal-1.0.0/src/chantal/plugins/rpm/modules.py +151 -0
- chantal-1.0.0/src/chantal/plugins/rpm/parsers.py +460 -0
- chantal-1.0.0/src/chantal/plugins/rpm/publisher.py +1097 -0
- chantal-1.0.0/src/chantal/plugins/rpm/rpm_header.py +115 -0
- chantal-1.0.0/src/chantal/plugins/rpm/sync.py +1108 -0
- chantal-1.0.0/src/chantal/plugins/rpm/updateinfo.py +325 -0
- chantal-1.0.0/src/chantal/plugins/view_publisher.py +186 -0
- chantal-1.0.0/src/chantal/py.typed +1 -0
- chantal-1.0.0/src/chantal.egg-info/PKG-INFO +353 -0
- chantal-1.0.0/src/chantal.egg-info/SOURCES.txt +58 -0
- chantal-1.0.0/src/chantal.egg-info/dependency_links.txt +1 -0
- chantal-1.0.0/src/chantal.egg-info/entry_points.txt +2 -0
- chantal-1.0.0/src/chantal.egg-info/requires.txt +25 -0
- chantal-1.0.0/src/chantal.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Include important files in source distribution
|
|
2
|
+
include README.md
|
|
3
|
+
include LICENSE
|
|
4
|
+
include pyproject.toml
|
|
5
|
+
include src/chantal/py.typed
|
|
6
|
+
|
|
7
|
+
# Exclude development files
|
|
8
|
+
exclude .gitignore
|
|
9
|
+
exclude .planning/*
|
|
10
|
+
exclude poc/*
|
|
11
|
+
recursive-exclude tests *
|
|
12
|
+
recursive-exclude * __pycache__
|
|
13
|
+
recursive-exclude * *.py[co]
|
chantal-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chantal
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Unified offline repository mirroring for RPM and APT
|
|
5
|
+
Author-email: Simon Lauger <simon@lauger.de>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/slauger/chantal
|
|
8
|
+
Project-URL: Documentation, https://github.com/slauger/chantal#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/slauger/chantal
|
|
10
|
+
Project-URL: Issues, https://github.com/slauger/chantal/issues
|
|
11
|
+
Keywords: rpm,yum,dnf,repository,mirror,sync,rhel,centos
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: System :: Archiving :: Mirroring
|
|
20
|
+
Classifier: Topic :: System :: Systems Administration
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: click>=8.1.7
|
|
24
|
+
Requires-Dist: pydantic>=2.5.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
26
|
+
Requires-Dist: packaging>=23.0
|
|
27
|
+
Requires-Dist: sqlalchemy>=2.0.23
|
|
28
|
+
Requires-Dist: psycopg2-binary>=2.9.9
|
|
29
|
+
Requires-Dist: alembic>=1.13.0
|
|
30
|
+
Requires-Dist: requests>=2.31.0
|
|
31
|
+
Requires-Dist: urllib3>=2.1.0
|
|
32
|
+
Requires-Dist: zstandard>=0.23.0
|
|
33
|
+
Requires-Dist: python-gnupg>=0.5.0
|
|
34
|
+
Requires-Dist: cryptography>=42.0
|
|
35
|
+
Requires-Dist: tqdm>=4.66.0
|
|
36
|
+
Requires-Dist: rich>=13.7.0
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest>=7.4.3; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-asyncio>=0.21.1; extra == "dev"
|
|
40
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
41
|
+
Requires-Dist: mypy==2.1.0; extra == "dev"
|
|
42
|
+
Requires-Dist: black==26.5.1; extra == "dev"
|
|
43
|
+
Requires-Dist: ruff>=0.1.6; extra == "dev"
|
|
44
|
+
Requires-Dist: yamllint>=1.35.0; extra == "dev"
|
|
45
|
+
Requires-Dist: types-PyYAML>=6.0.12; extra == "dev"
|
|
46
|
+
Requires-Dist: types-requests>=2.31.0; extra == "dev"
|
|
47
|
+
|
|
48
|
+
# Chantal
|
|
49
|
+
|
|
50
|
+
**_Because every other name was already taken._** - A unified CLI tool for offline repository mirroring.
|
|
51
|
+
|
|
52
|
+
[](https://slauger.github.io/chantal/)
|
|
53
|
+
[](https://github.com/slauger/chantal/pkgs/container/chantal)
|
|
54
|
+
[](LICENSE)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## What is Chantal?
|
|
59
|
+
|
|
60
|
+
A Python-based CLI tool for offline repository mirroring, inspired by pulp-admin, reposync, and aptly.
|
|
61
|
+
|
|
62
|
+
**The Problem:** Enterprise environments need offline mirrors of RPM/APT repositories with version control, efficient storage, RHEL subscription support, and simple management. Existing tools either:
|
|
63
|
+
- Support only one repository type (`reposync` for RPM, `apt-mirror` for APT)
|
|
64
|
+
- Require complex infrastructure (Pulp needs Celery, RabbitMQ, Redis, PostgreSQL)
|
|
65
|
+
- Lack proper snapshot and deduplication features
|
|
66
|
+
|
|
67
|
+
**The Solution:** One simple CLI tool. No daemons, no message queues, no complex setup. Just sync repositories, create snapshots, and publish static files. Works with any webserver (Apache, NGINX) - because it's just files.
|
|
68
|
+
|
|
69
|
+
## Features
|
|
70
|
+
|
|
71
|
+
- 🔄 **Unified Mirroring** - Multiple repository types in one tool (RPM, DEB/APT, Helm, Alpine APK)
|
|
72
|
+
- 📦 **Deduplication** - Content-addressed storage (SHA256), packages stored once
|
|
73
|
+
- 📸 **Snapshots** - Immutable point-in-time repository states for patch management
|
|
74
|
+
- 🔍 **Views** - Virtual repositories combining multiple repos (e.g., BaseOS + AppStream + EPEL)
|
|
75
|
+
- 🔌 **Modular** - Plugin architecture for repository types
|
|
76
|
+
- 🚫 **No Daemons** - Simple CLI tool (optional scheduler for future automation)
|
|
77
|
+
- 📁 **Static Output** - Serve with any webserver (Apache, NGINX)
|
|
78
|
+
- 🔐 **RHEL CDN Support** - Client certificate authentication for Red Hat repos
|
|
79
|
+
- 🎯 **Smart Filtering** - Pattern-based package filtering with post-processing
|
|
80
|
+
- 🪞 **Mirror & Filtered Modes** - Full metadata mirroring or filtered repos with regenerated metadata
|
|
81
|
+
- 🔏 **Metadata Signing** - Sign regenerated metadata in filtered mode: APT (InRelease/Release.gpg), RPM (repomd.xml.asc) and APK (RSA-signed APKINDEX) so clients can verify the repo
|
|
82
|
+
- ⚡ **Fast Updates** - Check for updates without downloading (like `dnf check-update`)
|
|
83
|
+
- 🚀 **Metadata Caching** - SHA256-based cache for RPM metadata (90-95% faster syncs for RHEL)
|
|
84
|
+
|
|
85
|
+
**Supported Repository Types:**
|
|
86
|
+
- ✅ **RPM/DNF/YUM** (RHEL, CentOS, Fedora, Rocky, AlmaLinux, EPEL)
|
|
87
|
+
- ✅ **DEB/APT** (Debian, Ubuntu)
|
|
88
|
+
- ✅ **Helm Charts** (Kubernetes, Bitnami, AWS EKS, Prometheus, GitLab)
|
|
89
|
+
- ✅ **Alpine APK** (Alpine Linux, container base images)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Quick Start
|
|
94
|
+
|
|
95
|
+
### Installation
|
|
96
|
+
|
|
97
|
+
**Option 1: Container (Recommended)**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Pull from GitHub Container Registry
|
|
101
|
+
docker pull ghcr.io/slauger/chantal:latest
|
|
102
|
+
|
|
103
|
+
# Run
|
|
104
|
+
docker run --rm \
|
|
105
|
+
-v $(pwd)/config:/etc/chantal:ro \
|
|
106
|
+
-v $(pwd)/data:/var/lib/chantal \
|
|
107
|
+
-v $(pwd)/repos:/var/www/repos \
|
|
108
|
+
ghcr.io/slauger/chantal:latest --help
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Option 2: Python Package**
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git clone https://github.com/slauger/chantal.git
|
|
115
|
+
cd chantal
|
|
116
|
+
pip install -e .
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Requirements:** Python 3.12+, PostgreSQL or SQLite
|
|
120
|
+
|
|
121
|
+
### Basic Usage
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 1. Initialize database schema
|
|
125
|
+
chantal db init
|
|
126
|
+
|
|
127
|
+
# 2. Configure repositories (see docs for examples)
|
|
128
|
+
vim /etc/chantal/config.yaml
|
|
129
|
+
|
|
130
|
+
# 3. Sync repository (RPM, Helm, or APK)
|
|
131
|
+
chantal repo sync --repo-id epel9-latest
|
|
132
|
+
|
|
133
|
+
# 4. Create snapshot
|
|
134
|
+
chantal snapshot create --repo-id epel9-latest --name 2025-01
|
|
135
|
+
|
|
136
|
+
# 5. Publish
|
|
137
|
+
chantal publish snapshot --snapshot epel9-latest-2025-01
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Result:** Published repository in `/var/www/repos/` ready to serve with Apache/NGINX.
|
|
141
|
+
|
|
142
|
+
### Database Management
|
|
143
|
+
|
|
144
|
+
Chantal uses Alembic for database schema migrations:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Initialize database schema (first-time setup)
|
|
148
|
+
chantal db init
|
|
149
|
+
|
|
150
|
+
# Check current schema version
|
|
151
|
+
chantal db current
|
|
152
|
+
|
|
153
|
+
# Check schema status and pending migrations
|
|
154
|
+
chantal db status
|
|
155
|
+
|
|
156
|
+
# Upgrade to latest schema version
|
|
157
|
+
chantal db upgrade
|
|
158
|
+
|
|
159
|
+
# View migration history
|
|
160
|
+
chantal db history
|
|
161
|
+
|
|
162
|
+
# Database statistics and verification
|
|
163
|
+
chantal db stats
|
|
164
|
+
chantal db verify
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Note:** Storage directories are created automatically when needed. The `db init` command only initializes the database schema.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Key Features
|
|
172
|
+
|
|
173
|
+
### Content-Addressed Storage
|
|
174
|
+
- SHA256-based deduplication (2-level directory: `ab/cd/sha256_file.rpm`)
|
|
175
|
+
- Packages stored once, shared across all repositories
|
|
176
|
+
- Typical deduplication: 60-80% across RHEL variants
|
|
177
|
+
|
|
178
|
+
### Immutable Snapshots
|
|
179
|
+
- Point-in-time freezes for patch management
|
|
180
|
+
- Compare snapshots (`chantal snapshot diff`)
|
|
181
|
+
- Rollback to previous states
|
|
182
|
+
- Atomic view snapshots (freeze all repos simultaneously)
|
|
183
|
+
|
|
184
|
+
### Virtual Repositories (Views)
|
|
185
|
+
- Combine multiple repos into one: `BaseOS + AppStream + CRB`
|
|
186
|
+
- Mixed repos: `RHEL + EPEL` in single repository
|
|
187
|
+
- Stack-specific views: web server, monitoring, etc.
|
|
188
|
+
|
|
189
|
+
### Smart Filtering
|
|
190
|
+
```yaml
|
|
191
|
+
filters:
|
|
192
|
+
patterns:
|
|
193
|
+
include: ["^nginx-.*", "^httpd-.*"]
|
|
194
|
+
exclude: [".*-debug.*"]
|
|
195
|
+
metadata:
|
|
196
|
+
architectures:
|
|
197
|
+
include: ["x86_64", "noarch"]
|
|
198
|
+
post_processing:
|
|
199
|
+
only_latest_version: true
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Zero-Copy Publishing
|
|
203
|
+
- Hardlinks (not copies) to published directories
|
|
204
|
+
- Instant publishing (milliseconds for thousands of packages)
|
|
205
|
+
- Atomic metadata updates
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Architecture
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
/var/lib/chantal/pool/ # Content-addressed storage (SHA256)
|
|
213
|
+
├── ab/cd/sha256_package.rpm
|
|
214
|
+
└── ...
|
|
215
|
+
|
|
216
|
+
/var/www/repos/ # Published repositories (hardlinks)
|
|
217
|
+
├── rhel9-baseos/
|
|
218
|
+
│ ├── latest/ # Current state
|
|
219
|
+
│ └── snapshots/2025-01/ # Immutable snapshot
|
|
220
|
+
└── views/
|
|
221
|
+
└── rhel9-complete/ # Virtual repository
|
|
222
|
+
└── latest/
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Database:** PostgreSQL or SQLite (SQLAlchemy models)
|
|
226
|
+
**Plugins:** Extensible architecture for repository types (RPM, DEB/APT, Helm, APK)
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Documentation
|
|
231
|
+
|
|
232
|
+
📚 **Full Documentation:** https://slauger.github.io/chantal/
|
|
233
|
+
|
|
234
|
+
- [Installation Guide](https://slauger.github.io/chantal/user-guide/installation.html)
|
|
235
|
+
- [Quick Start](https://slauger.github.io/chantal/user-guide/quickstart.html)
|
|
236
|
+
- [CLI Commands](https://slauger.github.io/chantal/user-guide/cli-commands.html)
|
|
237
|
+
- [Configuration](https://slauger.github.io/chantal/configuration/overview.html)
|
|
238
|
+
- [Views (Virtual Repositories)](https://slauger.github.io/chantal/user-guide/views.html)
|
|
239
|
+
- [Architecture](https://slauger.github.io/chantal/architecture/overview.html)
|
|
240
|
+
- [Plugin Development](https://slauger.github.io/chantal/plugins/custom-plugins.html)
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Common Workflows
|
|
245
|
+
|
|
246
|
+
### Patch Management
|
|
247
|
+
```bash
|
|
248
|
+
# Monthly cycle
|
|
249
|
+
chantal repo sync --all
|
|
250
|
+
chantal snapshot create --repo-id rhel9-baseos --name 2025-02
|
|
251
|
+
chantal snapshot diff --repo-id rhel9-baseos 2025-01 2025-02
|
|
252
|
+
chantal publish snapshot --snapshot rhel9-baseos-2025-02
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### RHEL Subscription
|
|
256
|
+
```yaml
|
|
257
|
+
repositories:
|
|
258
|
+
- id: rhel9-baseos
|
|
259
|
+
feed: https://cdn.redhat.com/content/dist/rhel9/9/x86_64/baseos/os
|
|
260
|
+
ssl:
|
|
261
|
+
client_cert: /etc/pki/entitlement/1234567890.pem
|
|
262
|
+
client_key: /etc/pki/entitlement/1234567890-key.pem
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Air-Gapped Environments
|
|
266
|
+
```bash
|
|
267
|
+
# Online system
|
|
268
|
+
chantal repo sync --all
|
|
269
|
+
tar czf export.tar.gz /var/lib/chantal /etc/chantal
|
|
270
|
+
|
|
271
|
+
# Offline system
|
|
272
|
+
tar xzf export.tar.gz
|
|
273
|
+
chantal publish repo --all
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
See [Workflows Documentation](https://slauger.github.io/chantal/user-guide/workflows.html) for more examples.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Contributing
|
|
281
|
+
|
|
282
|
+
Contributions welcome! See [GitHub Issues](https://github.com/slauger/chantal/issues) for planned features and improvements.
|
|
283
|
+
|
|
284
|
+
### Development Setup
|
|
285
|
+
|
|
286
|
+
**1. Clone and Setup Virtual Environment:**
|
|
287
|
+
```bash
|
|
288
|
+
git clone https://github.com/slauger/chantal.git
|
|
289
|
+
cd chantal
|
|
290
|
+
|
|
291
|
+
# Create virtual environment
|
|
292
|
+
make venv
|
|
293
|
+
# OR manually: python3 -m venv venv
|
|
294
|
+
|
|
295
|
+
# Activate virtual environment
|
|
296
|
+
source venv/bin/activate
|
|
297
|
+
|
|
298
|
+
# Install dependencies
|
|
299
|
+
make install-dev
|
|
300
|
+
# OR manually: pip install -e ".[dev]"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**2. Run Local Tests (CI/CD Checks):**
|
|
304
|
+
```bash
|
|
305
|
+
# IMPORTANT: Always use the Makefile targets to ensure correct venv usage!
|
|
306
|
+
|
|
307
|
+
# Run all linters (same as CI/CD)
|
|
308
|
+
make lint
|
|
309
|
+
|
|
310
|
+
# Run all checks (linters + tests)
|
|
311
|
+
make check
|
|
312
|
+
|
|
313
|
+
# Individual checks
|
|
314
|
+
make ruff # Linting
|
|
315
|
+
make black # Code formatting check
|
|
316
|
+
make yamllint # YAML linting
|
|
317
|
+
make mypy # Type checking
|
|
318
|
+
make pytest # Unit tests
|
|
319
|
+
|
|
320
|
+
# Auto-format code
|
|
321
|
+
make format
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**3. Development Notes:**
|
|
325
|
+
- ⚠️ **Always activate the venv** before running tests (`source venv/bin/activate`)
|
|
326
|
+
- ✅ **Use `make lint`** instead of running tools directly - ensures venv usage
|
|
327
|
+
- ✅ **CI/CD runs the same checks** as `make lint` - local = CI/CD
|
|
328
|
+
- 🔧 All linters are pinned to specific versions for consistency
|
|
329
|
+
- 📝 See `Makefile` for all available targets
|
|
330
|
+
|
|
331
|
+
Read the [Architecture Documentation](https://slauger.github.io/chantal/architecture/overview.html) before contributing.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
MIT License - See [LICENSE](LICENSE) file for details.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Credits
|
|
342
|
+
|
|
343
|
+
Developed by [Simon Lauger](https://github.com/slauger)
|
|
344
|
+
|
|
345
|
+
Inspired by: pulp-admin, reposync, aptly, apt-mirror, bandersnatch
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
**📦 Container Images:** `ghcr.io/slauger/chantal:latest`
|
|
350
|
+
|
|
351
|
+
**📚 Documentation:** https://slauger.github.io/chantal/
|
|
352
|
+
|
|
353
|
+
**🐛 Issues:** https://github.com/slauger/chantal/issues
|
chantal-1.0.0/README.md
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# Chantal
|
|
2
|
+
|
|
3
|
+
**_Because every other name was already taken._** - A unified CLI tool for offline repository mirroring.
|
|
4
|
+
|
|
5
|
+
[](https://slauger.github.io/chantal/)
|
|
6
|
+
[](https://github.com/slauger/chantal/pkgs/container/chantal)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What is Chantal?
|
|
12
|
+
|
|
13
|
+
A Python-based CLI tool for offline repository mirroring, inspired by pulp-admin, reposync, and aptly.
|
|
14
|
+
|
|
15
|
+
**The Problem:** Enterprise environments need offline mirrors of RPM/APT repositories with version control, efficient storage, RHEL subscription support, and simple management. Existing tools either:
|
|
16
|
+
- Support only one repository type (`reposync` for RPM, `apt-mirror` for APT)
|
|
17
|
+
- Require complex infrastructure (Pulp needs Celery, RabbitMQ, Redis, PostgreSQL)
|
|
18
|
+
- Lack proper snapshot and deduplication features
|
|
19
|
+
|
|
20
|
+
**The Solution:** One simple CLI tool. No daemons, no message queues, no complex setup. Just sync repositories, create snapshots, and publish static files. Works with any webserver (Apache, NGINX) - because it's just files.
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- 🔄 **Unified Mirroring** - Multiple repository types in one tool (RPM, DEB/APT, Helm, Alpine APK)
|
|
25
|
+
- 📦 **Deduplication** - Content-addressed storage (SHA256), packages stored once
|
|
26
|
+
- 📸 **Snapshots** - Immutable point-in-time repository states for patch management
|
|
27
|
+
- 🔍 **Views** - Virtual repositories combining multiple repos (e.g., BaseOS + AppStream + EPEL)
|
|
28
|
+
- 🔌 **Modular** - Plugin architecture for repository types
|
|
29
|
+
- 🚫 **No Daemons** - Simple CLI tool (optional scheduler for future automation)
|
|
30
|
+
- 📁 **Static Output** - Serve with any webserver (Apache, NGINX)
|
|
31
|
+
- 🔐 **RHEL CDN Support** - Client certificate authentication for Red Hat repos
|
|
32
|
+
- 🎯 **Smart Filtering** - Pattern-based package filtering with post-processing
|
|
33
|
+
- 🪞 **Mirror & Filtered Modes** - Full metadata mirroring or filtered repos with regenerated metadata
|
|
34
|
+
- 🔏 **Metadata Signing** - Sign regenerated metadata in filtered mode: APT (InRelease/Release.gpg), RPM (repomd.xml.asc) and APK (RSA-signed APKINDEX) so clients can verify the repo
|
|
35
|
+
- ⚡ **Fast Updates** - Check for updates without downloading (like `dnf check-update`)
|
|
36
|
+
- 🚀 **Metadata Caching** - SHA256-based cache for RPM metadata (90-95% faster syncs for RHEL)
|
|
37
|
+
|
|
38
|
+
**Supported Repository Types:**
|
|
39
|
+
- ✅ **RPM/DNF/YUM** (RHEL, CentOS, Fedora, Rocky, AlmaLinux, EPEL)
|
|
40
|
+
- ✅ **DEB/APT** (Debian, Ubuntu)
|
|
41
|
+
- ✅ **Helm Charts** (Kubernetes, Bitnami, AWS EKS, Prometheus, GitLab)
|
|
42
|
+
- ✅ **Alpine APK** (Alpine Linux, container base images)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### Installation
|
|
49
|
+
|
|
50
|
+
**Option 1: Container (Recommended)**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Pull from GitHub Container Registry
|
|
54
|
+
docker pull ghcr.io/slauger/chantal:latest
|
|
55
|
+
|
|
56
|
+
# Run
|
|
57
|
+
docker run --rm \
|
|
58
|
+
-v $(pwd)/config:/etc/chantal:ro \
|
|
59
|
+
-v $(pwd)/data:/var/lib/chantal \
|
|
60
|
+
-v $(pwd)/repos:/var/www/repos \
|
|
61
|
+
ghcr.io/slauger/chantal:latest --help
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Option 2: Python Package**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/slauger/chantal.git
|
|
68
|
+
cd chantal
|
|
69
|
+
pip install -e .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Requirements:** Python 3.12+, PostgreSQL or SQLite
|
|
73
|
+
|
|
74
|
+
### Basic Usage
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 1. Initialize database schema
|
|
78
|
+
chantal db init
|
|
79
|
+
|
|
80
|
+
# 2. Configure repositories (see docs for examples)
|
|
81
|
+
vim /etc/chantal/config.yaml
|
|
82
|
+
|
|
83
|
+
# 3. Sync repository (RPM, Helm, or APK)
|
|
84
|
+
chantal repo sync --repo-id epel9-latest
|
|
85
|
+
|
|
86
|
+
# 4. Create snapshot
|
|
87
|
+
chantal snapshot create --repo-id epel9-latest --name 2025-01
|
|
88
|
+
|
|
89
|
+
# 5. Publish
|
|
90
|
+
chantal publish snapshot --snapshot epel9-latest-2025-01
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Result:** Published repository in `/var/www/repos/` ready to serve with Apache/NGINX.
|
|
94
|
+
|
|
95
|
+
### Database Management
|
|
96
|
+
|
|
97
|
+
Chantal uses Alembic for database schema migrations:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Initialize database schema (first-time setup)
|
|
101
|
+
chantal db init
|
|
102
|
+
|
|
103
|
+
# Check current schema version
|
|
104
|
+
chantal db current
|
|
105
|
+
|
|
106
|
+
# Check schema status and pending migrations
|
|
107
|
+
chantal db status
|
|
108
|
+
|
|
109
|
+
# Upgrade to latest schema version
|
|
110
|
+
chantal db upgrade
|
|
111
|
+
|
|
112
|
+
# View migration history
|
|
113
|
+
chantal db history
|
|
114
|
+
|
|
115
|
+
# Database statistics and verification
|
|
116
|
+
chantal db stats
|
|
117
|
+
chantal db verify
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Note:** Storage directories are created automatically when needed. The `db init` command only initializes the database schema.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Key Features
|
|
125
|
+
|
|
126
|
+
### Content-Addressed Storage
|
|
127
|
+
- SHA256-based deduplication (2-level directory: `ab/cd/sha256_file.rpm`)
|
|
128
|
+
- Packages stored once, shared across all repositories
|
|
129
|
+
- Typical deduplication: 60-80% across RHEL variants
|
|
130
|
+
|
|
131
|
+
### Immutable Snapshots
|
|
132
|
+
- Point-in-time freezes for patch management
|
|
133
|
+
- Compare snapshots (`chantal snapshot diff`)
|
|
134
|
+
- Rollback to previous states
|
|
135
|
+
- Atomic view snapshots (freeze all repos simultaneously)
|
|
136
|
+
|
|
137
|
+
### Virtual Repositories (Views)
|
|
138
|
+
- Combine multiple repos into one: `BaseOS + AppStream + CRB`
|
|
139
|
+
- Mixed repos: `RHEL + EPEL` in single repository
|
|
140
|
+
- Stack-specific views: web server, monitoring, etc.
|
|
141
|
+
|
|
142
|
+
### Smart Filtering
|
|
143
|
+
```yaml
|
|
144
|
+
filters:
|
|
145
|
+
patterns:
|
|
146
|
+
include: ["^nginx-.*", "^httpd-.*"]
|
|
147
|
+
exclude: [".*-debug.*"]
|
|
148
|
+
metadata:
|
|
149
|
+
architectures:
|
|
150
|
+
include: ["x86_64", "noarch"]
|
|
151
|
+
post_processing:
|
|
152
|
+
only_latest_version: true
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Zero-Copy Publishing
|
|
156
|
+
- Hardlinks (not copies) to published directories
|
|
157
|
+
- Instant publishing (milliseconds for thousands of packages)
|
|
158
|
+
- Atomic metadata updates
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Architecture
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
/var/lib/chantal/pool/ # Content-addressed storage (SHA256)
|
|
166
|
+
├── ab/cd/sha256_package.rpm
|
|
167
|
+
└── ...
|
|
168
|
+
|
|
169
|
+
/var/www/repos/ # Published repositories (hardlinks)
|
|
170
|
+
├── rhel9-baseos/
|
|
171
|
+
│ ├── latest/ # Current state
|
|
172
|
+
│ └── snapshots/2025-01/ # Immutable snapshot
|
|
173
|
+
└── views/
|
|
174
|
+
└── rhel9-complete/ # Virtual repository
|
|
175
|
+
└── latest/
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Database:** PostgreSQL or SQLite (SQLAlchemy models)
|
|
179
|
+
**Plugins:** Extensible architecture for repository types (RPM, DEB/APT, Helm, APK)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Documentation
|
|
184
|
+
|
|
185
|
+
📚 **Full Documentation:** https://slauger.github.io/chantal/
|
|
186
|
+
|
|
187
|
+
- [Installation Guide](https://slauger.github.io/chantal/user-guide/installation.html)
|
|
188
|
+
- [Quick Start](https://slauger.github.io/chantal/user-guide/quickstart.html)
|
|
189
|
+
- [CLI Commands](https://slauger.github.io/chantal/user-guide/cli-commands.html)
|
|
190
|
+
- [Configuration](https://slauger.github.io/chantal/configuration/overview.html)
|
|
191
|
+
- [Views (Virtual Repositories)](https://slauger.github.io/chantal/user-guide/views.html)
|
|
192
|
+
- [Architecture](https://slauger.github.io/chantal/architecture/overview.html)
|
|
193
|
+
- [Plugin Development](https://slauger.github.io/chantal/plugins/custom-plugins.html)
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Common Workflows
|
|
198
|
+
|
|
199
|
+
### Patch Management
|
|
200
|
+
```bash
|
|
201
|
+
# Monthly cycle
|
|
202
|
+
chantal repo sync --all
|
|
203
|
+
chantal snapshot create --repo-id rhel9-baseos --name 2025-02
|
|
204
|
+
chantal snapshot diff --repo-id rhel9-baseos 2025-01 2025-02
|
|
205
|
+
chantal publish snapshot --snapshot rhel9-baseos-2025-02
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### RHEL Subscription
|
|
209
|
+
```yaml
|
|
210
|
+
repositories:
|
|
211
|
+
- id: rhel9-baseos
|
|
212
|
+
feed: https://cdn.redhat.com/content/dist/rhel9/9/x86_64/baseos/os
|
|
213
|
+
ssl:
|
|
214
|
+
client_cert: /etc/pki/entitlement/1234567890.pem
|
|
215
|
+
client_key: /etc/pki/entitlement/1234567890-key.pem
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Air-Gapped Environments
|
|
219
|
+
```bash
|
|
220
|
+
# Online system
|
|
221
|
+
chantal repo sync --all
|
|
222
|
+
tar czf export.tar.gz /var/lib/chantal /etc/chantal
|
|
223
|
+
|
|
224
|
+
# Offline system
|
|
225
|
+
tar xzf export.tar.gz
|
|
226
|
+
chantal publish repo --all
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
See [Workflows Documentation](https://slauger.github.io/chantal/user-guide/workflows.html) for more examples.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Contributing
|
|
234
|
+
|
|
235
|
+
Contributions welcome! See [GitHub Issues](https://github.com/slauger/chantal/issues) for planned features and improvements.
|
|
236
|
+
|
|
237
|
+
### Development Setup
|
|
238
|
+
|
|
239
|
+
**1. Clone and Setup Virtual Environment:**
|
|
240
|
+
```bash
|
|
241
|
+
git clone https://github.com/slauger/chantal.git
|
|
242
|
+
cd chantal
|
|
243
|
+
|
|
244
|
+
# Create virtual environment
|
|
245
|
+
make venv
|
|
246
|
+
# OR manually: python3 -m venv venv
|
|
247
|
+
|
|
248
|
+
# Activate virtual environment
|
|
249
|
+
source venv/bin/activate
|
|
250
|
+
|
|
251
|
+
# Install dependencies
|
|
252
|
+
make install-dev
|
|
253
|
+
# OR manually: pip install -e ".[dev]"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**2. Run Local Tests (CI/CD Checks):**
|
|
257
|
+
```bash
|
|
258
|
+
# IMPORTANT: Always use the Makefile targets to ensure correct venv usage!
|
|
259
|
+
|
|
260
|
+
# Run all linters (same as CI/CD)
|
|
261
|
+
make lint
|
|
262
|
+
|
|
263
|
+
# Run all checks (linters + tests)
|
|
264
|
+
make check
|
|
265
|
+
|
|
266
|
+
# Individual checks
|
|
267
|
+
make ruff # Linting
|
|
268
|
+
make black # Code formatting check
|
|
269
|
+
make yamllint # YAML linting
|
|
270
|
+
make mypy # Type checking
|
|
271
|
+
make pytest # Unit tests
|
|
272
|
+
|
|
273
|
+
# Auto-format code
|
|
274
|
+
make format
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**3. Development Notes:**
|
|
278
|
+
- ⚠️ **Always activate the venv** before running tests (`source venv/bin/activate`)
|
|
279
|
+
- ✅ **Use `make lint`** instead of running tools directly - ensures venv usage
|
|
280
|
+
- ✅ **CI/CD runs the same checks** as `make lint` - local = CI/CD
|
|
281
|
+
- 🔧 All linters are pinned to specific versions for consistency
|
|
282
|
+
- 📝 See `Makefile` for all available targets
|
|
283
|
+
|
|
284
|
+
Read the [Architecture Documentation](https://slauger.github.io/chantal/architecture/overview.html) before contributing.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
MIT License - See [LICENSE](LICENSE) file for details.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Credits
|
|
295
|
+
|
|
296
|
+
Developed by [Simon Lauger](https://github.com/slauger)
|
|
297
|
+
|
|
298
|
+
Inspired by: pulp-admin, reposync, aptly, apt-mirror, bandersnatch
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
**📦 Container Images:** `ghcr.io/slauger/chantal:latest`
|
|
303
|
+
|
|
304
|
+
**📚 Documentation:** https://slauger.github.io/chantal/
|
|
305
|
+
|
|
306
|
+
**🐛 Issues:** https://github.com/slauger/chantal/issues
|