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.
Files changed (60) hide show
  1. chantal-1.0.0/MANIFEST.in +13 -0
  2. chantal-1.0.0/PKG-INFO +353 -0
  3. chantal-1.0.0/README.md +306 -0
  4. chantal-1.0.0/pyproject.toml +186 -0
  5. chantal-1.0.0/setup.cfg +4 -0
  6. chantal-1.0.0/src/chantal/__init__.py +22 -0
  7. chantal-1.0.0/src/chantal/cli/__init__.py +3 -0
  8. chantal-1.0.0/src/chantal/cli/cache_commands.py +217 -0
  9. chantal-1.0.0/src/chantal/cli/content_commands.py +519 -0
  10. chantal-1.0.0/src/chantal/cli/db_commands.py +505 -0
  11. chantal-1.0.0/src/chantal/cli/main.py +146 -0
  12. chantal-1.0.0/src/chantal/cli/pool_commands.py +449 -0
  13. chantal-1.0.0/src/chantal/cli/publish_commands.py +727 -0
  14. chantal-1.0.0/src/chantal/cli/repo_commands.py +1418 -0
  15. chantal-1.0.0/src/chantal/cli/snapshot_commands.py +984 -0
  16. chantal-1.0.0/src/chantal/cli/view_commands.py +181 -0
  17. chantal-1.0.0/src/chantal/core/__init__.py +38 -0
  18. chantal-1.0.0/src/chantal/core/cache.py +315 -0
  19. chantal-1.0.0/src/chantal/core/config.py +957 -0
  20. chantal-1.0.0/src/chantal/core/downloader.py +403 -0
  21. chantal-1.0.0/src/chantal/core/gpg.py +300 -0
  22. chantal-1.0.0/src/chantal/core/gpg_verify.py +181 -0
  23. chantal-1.0.0/src/chantal/core/output.py +259 -0
  24. chantal-1.0.0/src/chantal/core/storage.py +382 -0
  25. chantal-1.0.0/src/chantal/db/__init__.py +32 -0
  26. chantal-1.0.0/src/chantal/db/connection.py +89 -0
  27. chantal-1.0.0/src/chantal/db/migrations.py +219 -0
  28. chantal-1.0.0/src/chantal/db/models.py +518 -0
  29. chantal-1.0.0/src/chantal/plugins/__init__.py +13 -0
  30. chantal-1.0.0/src/chantal/plugins/apk/models.py +128 -0
  31. chantal-1.0.0/src/chantal/plugins/apk/publisher.py +297 -0
  32. chantal-1.0.0/src/chantal/plugins/apk/signing.py +183 -0
  33. chantal-1.0.0/src/chantal/plugins/apk/sync.py +531 -0
  34. chantal-1.0.0/src/chantal/plugins/apt/__init__.py +19 -0
  35. chantal-1.0.0/src/chantal/plugins/apt/gpg.py +12 -0
  36. chantal-1.0.0/src/chantal/plugins/apt/models.py +178 -0
  37. chantal-1.0.0/src/chantal/plugins/apt/parsers.py +532 -0
  38. chantal-1.0.0/src/chantal/plugins/apt/publisher.py +819 -0
  39. chantal-1.0.0/src/chantal/plugins/apt/sync.py +1260 -0
  40. chantal-1.0.0/src/chantal/plugins/base.py +143 -0
  41. chantal-1.0.0/src/chantal/plugins/helm/models.py +130 -0
  42. chantal-1.0.0/src/chantal/plugins/helm/publisher.py +260 -0
  43. chantal-1.0.0/src/chantal/plugins/helm/sync.py +507 -0
  44. chantal-1.0.0/src/chantal/plugins/rpm/compression.py +145 -0
  45. chantal-1.0.0/src/chantal/plugins/rpm/filters.py +287 -0
  46. chantal-1.0.0/src/chantal/plugins/rpm/models.py +49 -0
  47. chantal-1.0.0/src/chantal/plugins/rpm/modules.py +151 -0
  48. chantal-1.0.0/src/chantal/plugins/rpm/parsers.py +460 -0
  49. chantal-1.0.0/src/chantal/plugins/rpm/publisher.py +1097 -0
  50. chantal-1.0.0/src/chantal/plugins/rpm/rpm_header.py +115 -0
  51. chantal-1.0.0/src/chantal/plugins/rpm/sync.py +1108 -0
  52. chantal-1.0.0/src/chantal/plugins/rpm/updateinfo.py +325 -0
  53. chantal-1.0.0/src/chantal/plugins/view_publisher.py +186 -0
  54. chantal-1.0.0/src/chantal/py.typed +1 -0
  55. chantal-1.0.0/src/chantal.egg-info/PKG-INFO +353 -0
  56. chantal-1.0.0/src/chantal.egg-info/SOURCES.txt +58 -0
  57. chantal-1.0.0/src/chantal.egg-info/dependency_links.txt +1 -0
  58. chantal-1.0.0/src/chantal.egg-info/entry_points.txt +2 -0
  59. chantal-1.0.0/src/chantal.egg-info/requires.txt +25 -0
  60. 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
+ [![Documentation](https://img.shields.io/badge/docs-read%20the%20docs-blue)](https://slauger.github.io/chantal/)
53
+ [![Container](https://img.shields.io/badge/container-ghcr.io-blue)](https://github.com/slauger/chantal/pkgs/container/chantal)
54
+ [![License](https://img.shields.io/badge/license-MIT-green)](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
@@ -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
+ [![Documentation](https://img.shields.io/badge/docs-read%20the%20docs-blue)](https://slauger.github.io/chantal/)
6
+ [![Container](https://img.shields.io/badge/container-ghcr.io-blue)](https://github.com/slauger/chantal/pkgs/container/chantal)
7
+ [![License](https://img.shields.io/badge/license-MIT-green)](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