Skip to content

Commit 3de1c00

Browse files
committed
Add MIT License and update README for chunked upload improvements
1 parent 79c6718 commit 3de1c00

File tree

2 files changed

+23
-173
lines changed

2 files changed

+23
-173
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 yorelog
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 2 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ This tool implements **streaming-based layer processing** using the OCI client l
2121

2222
-**Streaming Downloads**: Layers are streamed directly to disk without loading into memory
2323
-**Sequential Processing**: Processes one layer at a time to minimize memory footprint
24-
-**Chunked Uploads**: Large layers (>100MB) are read in 50MB chunks during upload
24+
-**Chunked Uploads**: Layers ≥500MB stream in ~5MB chunks (auto-expands when registries demand larger slices)
2525
-**Local Caching**: Efficient caching system for faster subsequent operations
2626
-**Progress Monitoring**: Real-time feedback on transfer progress and layer sizes
2727

@@ -47,12 +47,6 @@ can be embedded in other tools. It exposes:
4747
Rust itself treats the `core` crate. This keeps the CLI boundary clean while enabling other
4848
projects to reuse the same stable OCI primitives without pulling in the rest of the binary.
4949

50-
## 📋 Prerequisites
51-
52-
- **Rust**: Version 1.70 or later
53-
- **Network Access**: To source and target registries
54-
- **Disk Space**: Sufficient space for caching large images
55-
5650
## 🛠️ Installation
5751

5852
### Download Pre-built Binaries (Recommended)
@@ -143,11 +137,6 @@ The `push` command now handles most of the bookkeeping automatically:
143137
- imports `docker save` archives on the fly before uploading
144138
- reuses saved logins unless you pass explicit `--username/--password`
145139

146-
### Tips
147-
148-
- Need a different account temporarily? Pass `--username/--password` (or use env vars such as `DOCKER_USERNAME`) and they override stored credentials for that run only.
149-
- Prefer scripting? Keep everything declarative: `login` once inside CI, then run `pull`, `push`, done.
150-
- Unsure what target was used last time? Run `push` without `-t`; the history-based inference will suggest a sane default and print it before uploading.
151140

152141
## 🏗️ Architecture
153142

@@ -193,168 +182,8 @@ Tar archives produced by `save` live wherever you choose to write them (current
193182
4. **Layer/config upload** – reuse existing blobs when present, otherwise stream in fixed-size chunks with telemetry.
194183
5. **Manifest publish** – rebuild the OCI manifest and push it once all blobs are present.
195184

196-
### Layer Processing Strategies
197-
198-
| Layer Size | Strategy | Memory Usage | Description |
199-
|------------|----------|--------------|-------------|
200-
| < 100MB | Direct Read | ~Layer Size | Read entire layer into memory |
201-
| > 100MB | Chunked Read | ~50MB | Read in 50MB chunks with delays |
202-
| Any Size | Streaming | ~Buffer Size | Direct stream to/from disk |
203-
| Pipeline | Parallel Uploads | ~Buffer Size per worker | Extraction publishes layers into an async queue while up to 3 concurrent upload tasks push blobs |
204-
205-
Layer extraction now feeds an async channel as soon as each blob hits disk, so uploading overlaps with the remaining tar processing. The default concurrency spins up three upload tasks (tunable in code) to take advantage of multi-core hosts and higher latency links, while still honoring the sequential manifest ordering when publishing.
206-
207-
## 🔧 Configuration
208-
209-
### Client Configuration
210-
211-
The tool uses these default settings:
212-
213-
```rust
214-
// Platform resolver for multi-arch images
215-
platform_resolver = linux_amd64_resolver
216-
217-
// Authentication methods
218-
- Anonymous (for public registries)
219-
- Basic Auth (username/password)
220-
221-
// Chunk size for large layers
222-
chunk_size = 50MB
223-
224-
// Rate limiting delays
225-
large_layer_delay = 200ms
226-
chunk_delay = 10ms
227-
```
228-
229-
### Customization
230-
231-
You can modify these settings in `src/main.rs`:
232-
233-
```rust
234-
// Adjust chunk size for very large layers
235-
let chunk_size = 100 * 1024 * 1024; // 100MB chunks
236-
237-
// Modify size threshold for chunked processing
238-
if layer_size_mb > 50.0 { // Lower threshold
239-
// Use chunked approach
240-
}
241-
242-
// Adjust rate limiting
243-
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; // Longer delay
244-
```
245-
246-
### Debugging OCI Traffic
247-
248-
Set the following environment variables to inspect the raw OCI flow without recompiling:
249-
250-
| Variable | Effect |
251-
|----------|--------|
252-
| `OCI_DEBUG=1` | Logs every HTTP request/response handled by the internal OCI client (method, URL, status, scope). |
253-
| `OCI_DEBUG_UPLOAD=1` | Adds detailed tracing for blob uploads (upload session URLs, redirects, finalization). Inherits `OCI_DEBUG` when set. |
254-
255-
These logs run through `println!`, so they appear directly in the CLI output and can be piped to files for troubleshooting.
256-
257-
## 📊 Performance Comparison
258-
259-
### Memory Usage (Processing 5GB Image)
260-
261-
| Method | Peak Memory | Notes |
262-
|--------|-------------|-------|
263-
| Traditional Docker | ~5.2GB | Loads layers into memory |
264-
| **This Tool** | ~50MB | Streams with chunked processing |
265-
266-
### Transfer Speed
267-
268-
- **Network bound**: Performance limited by network speed
269-
- **Consistent memory**: No memory-related slowdowns
270-
- **Parallel-safe**: Can run multiple instances without memory conflicts
271-
272-
## 🐛 Troubleshooting
273-
274-
### Common Issues
275-
276-
#### "Authentication failed"
277-
```bash
278-
Error: Push error: Authentication failed: ...
279-
```
280-
**Solution**: Verify username/password and registry permissions
281-
282-
#### "No local images detected via <runtime>"
283-
```bash
284-
Error: No local images detected via docker
285-
```
286-
**Solution**: Ensure the image exists locally (e.g., `docker images`) or pass it explicitly to `save`.
287-
288-
#### "Failed to create state directory"
289-
```bash
290-
Error: Cache error: Failed to create state directory ...
291-
```
292-
**Solution**: Verify you have write access to the current working directory (or set `STATE_DIR` via environment variables, if you relocate it in code).
293-
294-
#### Memory Issues (Still occurring)
295-
If you're still experiencing memory issues:
296-
297-
1. **Check chunk size**: Reduce chunk size in code
298-
2. **Monitor disk space**: Ensure sufficient space for caching
299-
3. **Close other applications**: Free up system memory
300-
4. **Use sequential processing**: Avoid concurrent operations
301-
302-
### Debug Mode
303-
304-
Add debug logging by setting environment variable:
305-
```bash
306-
RUST_LOG=debug docker-image-pusher pull nginx:latest
307-
```
308-
309-
## 🤝 Contributing
310-
311-
### Development Setup
312-
313-
```bash
314-
git clone <repository-url>
315-
cd docker-image-pusher
316-
cargo build
317-
cargo test
318-
```
319-
320-
### Code Structure
321-
322-
- `src/main.rs` - Lean CLI + shared constants (delegates to modules)
323-
- `src/push.rs` - Push/import workflow, target inference, confirmation prompts
324-
- `src/tar_import.rs` - Tar parsing, RepoTag helpers, import pipeline
325-
- `src/cache.rs` - Pull and caching logic with streaming
326-
- `src/state.rs` - Credential storage + push history tracking
327-
- `PusherError` - Custom error type re-exported from `main.rs`
328-
329-
### Adding Features
330-
331-
1. **New authentication methods**: Extend `RegistryAuth` usage
332-
2. **Progress bars**: Add progress indication for long transfers
333-
3. **Compression**: Add layer compression/decompression support
334-
4. **Parallel processing**: Implement safe concurrent layer transfers
335-
336-
## 📄 License
337-
338-
[Add your license information here]
339-
340-
## 🔗 Dependencies
341-
342-
- **oci-client**: OCI registry client with streaming support
343-
- **tokio**: Async runtime for concurrent operations
344-
- **clap**: Command-line argument parsing
345-
- **serde_json**: JSON serialization for metadata
346-
- **thiserror**: Structured error handling
347-
348-
## 📈 Future Enhancements
349185

350-
- [ ] Progress bars for long transfers
351-
- [ ] Resume interrupted transfers
352-
- [ ] Compression optimization
353-
- [ ] Multi-registry synchronization
354-
- [ ] Garbage collection for cache
355-
- [ ] Configuration file support
356-
- [ ] Integration with CI/CD pipelines
186+
## 🤝 Welcome Contributing
357187

358-
---
359188

360189
**Happy Docker image transferring! 🐳**

0 commit comments

Comments
 (0)