apt-dnf-bridge-workspace/README.md
robojerk 88d57cd3a1 Add enhanced rollback functionality and comprehensive documentation
- Implement two-phase rollback system inspired by apt-tx project
- Add package state tracking (newly_installed, upgraded, previously_installed)
- Enhance both core and advanced transaction APIs with rollback methods
- Add comprehensive rollback documentation in docs/rollback.md
- Create rollback_demo.rs example demonstrating functionality
- Update README with detailed crate usage instructions
- Add rollback features to feature flags documentation
- Fix import issues in advanced crate modules
- Add get_installed_packages method to AptCommands
- Include both crates.io and git installation options in README
2025-09-13 21:02:29 -07:00

486 lines
13 KiB
Markdown

# APT-DNF Bridge
A DNF-like bridge around APT for apt-ostree integration. This workspace provides a transaction-based API that makes APT work like DNF, complete with sophisticated rollback functionality.
## ✨ **Key Features**
- **🔄 Advanced Rollback**: Two-phase rollback system that tracks and undoes package changes
- **📦 Transaction Model**: DNF-like imperative transactions with resolve and commit phases
- **🔧 Pluggable Backends**: Shell, mock, and libapt backends for different use cases
- **⚡ Feature Flags**: Choose between minimal core or full advanced functionality
- **🛡️ Error Handling**: Comprehensive error handling with clear messages
- **📚 Complete Documentation**: Detailed guides and working examples
## 🎯 **Two-Crate Approach**
This workspace implements the refined two-crate approach with feature flags:
- **`apt-dnf-bridge-core`** - Minimal shell-out implementation
- **`apt-dnf-bridge`** - Main crate that re-exports core + optional advanced features
- **`apt-dnf-bridge-advanced`** - Pluggable backends, caching, and enhanced features
## 🚀 **Quick Start**
### Core (Minimal)
```toml
[dependencies]
apt-dnf-bridge = "0.1"
```
### Advanced Features
```toml
[dependencies]
apt-dnf-bridge = { version = "0.1", features = ["advanced"] }
```
## 📁 **Workspace Structure**
```
apt-dnf-bridge-workspace/
├── Cargo.toml # Workspace root
├── apt-dnf-bridge-core/ # Minimal implementation
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs
│ ├── command.rs
│ ├── error.rs
│ ├── package.rs
│ ├── repository.rs
│ └── transaction.rs
├── apt-dnf-bridge/ # Main public crate
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
├── apt-dnf-bridge-advanced/ # Advanced features
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs
│ ├── backend.rs
│ ├── package_v2.rs
│ ├── transaction_v2.rs
│ └── backend/
│ ├── shell_backend.rs
│ ├── mock_backend.rs
│ └── libapt_backend.rs
└── examples/ # Shared examples
├── basic_usage.rs
├── package_query.rs
├── atomicity_notes.rs
├── backend_selection.rs
└── rollback_demo.rs
```
## 🔧 **Usage Examples**
### Basic Usage (Core Only)
```rust
use apt_dnf_bridge::{Transaction, Package, Repository};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a transaction
let mut tx = Transaction::new();
// Add packages to install
let vim = Package::new("vim", "2:8.1.2269-1ubuntu5.14", "amd64");
tx.add_install(vim).await?;
// Resolve dependencies (APT handles automatically)
tx.resolve().await?;
// Commit the transaction
tx.commit().await?;
Ok(())
}
```
### Advanced Usage (With Backends)
```rust
use apt_dnf_bridge::{TransactionV2, PackageDatabaseV2, BackendFactory};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create transaction with auto-detected backend
let mut tx = TransactionV2::new().await?;
// Add packages
let vim = Package::new("vim", "2:8.1.2269-1ubuntu5.14", "amd64");
tx.add_install(vim).await?;
// Resolve and commit
tx.resolve().await?;
tx.commit().await?;
Ok(())
}
```
### Rollback Functionality
```rust
use apt_dnf_bridge::{Transaction, Package};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut tx = Transaction::new();
// Add packages
tx.add_install(Package::new("vim", "", "")).await?;
tx.add_install(Package::new("curl", "", "")).await?;
// Commit transaction
tx.resolve().await?;
tx.commit().await?;
// Later, rollback if needed
if tx.can_rollback() {
println!("Rolling back {} newly installed packages", tx.newly_installed().len());
tx.rollback().await?;
}
Ok(())
}
```
## 🏗️ **Building and Testing**
### Build All Crates
```bash
cargo build
```
### Test Core Features
```bash
cargo test -p apt-dnf-bridge-core
```
### Test Advanced Features
```bash
cargo test -p apt-dnf-bridge-advanced
```
### Run Examples
```bash
# Core examples
cargo run --example basic_usage
cargo run --example package_query
# Advanced examples (requires advanced feature)
cargo run --example backend_selection --features advanced
cargo run --example rollback_demo --features advanced
```
## 🎯 **Feature Flags**
### Core Features (Default)
- Shell-out APT commands
- Basic transaction model
- Package querying
- Repository management
- **🔄 Rollback functionality** (two-phase rollback)
- Error handling
### Advanced Features (`advanced` feature)
- Pluggable backends (shell, mock, libapt)
- Caching system
- Enhanced error handling
- Backend statistics
- Mock backend for testing
- **🔄 Advanced rollback** (backend-integrated)
## 📦 **Using as a Crate**
### Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
apt-dnf-bridge = "0.1"
```
For advanced features:
```toml
[dependencies]
apt-dnf-bridge = { version = "0.1", features = ["advanced"] }
```
Or using git directly:
```toml
[dependencies]
apt-dnf-bridge = { git = "https://git.raines.xyz/particle-os/apt-dnf-bridge-workspace.git", features = ["advanced"] }
```
### Basic Usage
#### 1. Core API (Minimal)
```rust
use apt_dnf_bridge::{Transaction, Package, Repository};
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Create a transaction
let mut tx = Transaction::new();
// Add packages to install
let vim = Package::new("vim", "2:8.1.2269-1ubuntu5.14", "amd64");
tx.add_install(vim).await?;
// Resolve dependencies
tx.resolve().await?;
// Commit the transaction
tx.commit().await?;
// Check what was installed
println!("Newly installed: {:?}", tx.newly_installed());
// Rollback if needed
if tx.can_rollback() {
tx.rollback().await?;
}
Ok(())
}
```
#### 2. Advanced API (With Backends)
```rust
use apt_dnf_bridge::{TransactionV2, PackageDatabaseV2, BackendConfig};
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Create transaction with specific backend
let config = BackendConfig::default();
let mut tx = TransactionV2::with_shell_backend(config).await?;
// Add packages
let git = Package::new("git", "1:2.25.1-1ubuntu3.11", "amd64");
tx.add_install(git).await?;
// Resolve and commit
tx.resolve().await?;
tx.commit().await?;
// Advanced rollback with backend
if tx.can_rollback() {
println!("Changed packages: {:?}", tx.changed_packages());
tx.rollback().await?;
}
Ok(())
}
```
#### 3. Package Querying
```rust
use apt_dnf_bridge::{PackageDatabase, Package};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut db = PackageDatabase::new();
// Search for packages
let packages = db.find_packages("editor").await?;
for package in packages {
println!("Found: {} - {}", package.name, package.version);
}
// Get specific package info
if let Some(package) = db.get_package_info("vim").await? {
println!("Package: {} v{}", package.name, package.version);
}
Ok(())
}
```
#### 4. Repository Management
```rust
use apt_dnf_bridge::{Repository, PackageDatabase};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Add a repository
let mut repo = Repository::new("myrepo", "https://example.com/debian");
repo.add_component("main");
repo.add_component("contrib");
repo.save_to_sources_list_d("myrepo.list")?;
// Update package cache
let mut db = PackageDatabase::new();
db.update_cache().await?;
Ok(())
}
```
### Error Handling
The crate uses `anyhow::Result` for error handling:
```rust
use anyhow::Result;
async fn example() -> Result<()> {
let mut tx = Transaction::new();
// All operations return Result<T, anyhow::Error>
tx.add_install(Package::new("vim", "", "")).await?;
tx.resolve().await?;
tx.commit().await?;
Ok(())
}
```
### Rollback System
The rollback system tracks package changes and provides two-phase rollback:
```rust
use apt_dnf_bridge::{Transaction, Package};
async fn rollback_example() -> Result<(), Box<dyn std::error::Error>> {
let mut tx = Transaction::new();
// Add packages
tx.add_install(Package::new("vim", "", "")).await?;
tx.add_install(Package::new("curl", "", "")).await?;
// Commit
tx.resolve().await?;
tx.commit().await?;
// Check rollback information
println!("Previously installed: {} packages", tx.previously_installed().len());
println!("Newly installed: {} packages", tx.newly_installed().len());
println!("Upgraded: {} packages", tx.upgraded().len());
// Rollback if needed
if tx.can_rollback() {
println!("Rolling back changes...");
tx.rollback().await?;
println!("Rollback completed");
}
Ok(())
}
```
### Feature Flags
#### Core Only (Default)
```toml
[dependencies]
apt-dnf-bridge = "0.1"
```
#### With Advanced Features
```toml
[dependencies]
apt-dnf-bridge = { version = "0.1", features = ["advanced"] }
```
### Available Examples
```bash
# Run examples
cargo run --example basic_usage
cargo run --example package_query
cargo run --example rollback_demo --features advanced
cargo run --example backend_selection --features advanced
```
## 🔄 **Migration Guide**
### From Single Crate to Workspace
1. **Core users**: No changes needed - same API
2. **Advanced users**: Add `features = ["advanced"]` to Cargo.toml
3. **New users**: Start with core, add advanced when needed
### API Compatibility
- Core API remains unchanged
- Advanced API available via feature flag
- Gradual adoption path supported
## 🔄 **Rollback System**
The APT-DNF Bridge includes a sophisticated two-phase rollback system inspired by the [apt-tx project](https://git.raines.xyz/particle-os/apt-tx):
### How It Works
1. **Package Tracking**: Tracks `previously_installed`, `newly_installed`, and `upgraded` packages
2. **Two-Phase Rollback**:
- **Phase 1**: Remove newly installed packages using `apt remove -y`
- **Phase 2**: Downgrade upgraded packages using `apt install -y package=oldversion`
### Rollback API
```rust
// Check if rollback is possible
if tx.can_rollback() {
// Get rollback information
println!("Newly installed: {:?}", tx.newly_installed());
println!("Upgraded: {:?}", tx.upgraded());
// Perform rollback
tx.rollback().await?;
}
```
### Limitations
- ✅ New package installations
- ✅ Package upgrades with available previous versions
- ❌ Complex dependency changes
- ❌ Configuration file modifications
- ❌ Concurrent package operations
For critical systems, consider using OSTree's native checkpoint/rollback functionality.
## 📚 **Documentation**
- **Core API**: Focus on simplicity and reliability
- **Advanced API**: Focus on power and flexibility
- **Rollback Guide**: Detailed rollback implementation (`docs/rollback.md`)
- **Examples**: Demonstrate both core and advanced usage
- **Migration**: Guide for moving between feature levels
## 🚀 **Benefits of This Approach**
1. **Single Crate** - No confusion about which to use
2. **Feature Flags** - Users choose complexity level
3. **Workspace** - Easy version coordination
4. **Re-exports** - Clean API surface
5. **Gradual Adoption** - Start simple, add complexity when needed
6. **Clear Documentation** - One README with feature explanations
7. **🔄 Advanced Rollback** - Production-ready rollback functionality
8. **🔧 Pluggable Backends** - Flexible backend architecture
This approach gives us all the benefits of the two-crate strategy with much better UX and maintenance.
## 📊 **Project Status**
-**Core Functionality**: Complete and tested
-**Rollback System**: Implemented with two-phase approach
-**Advanced Features**: Pluggable backends and caching
-**Documentation**: Comprehensive guides and examples
-**Examples**: Working demonstrations of all features
- 🔄 **Testing**: Unit tests and integration tests
- 📦 **Publishing**: Ready for crates.io publication
## 🤝 **Contributing**
This project is designed for apt-ostree integration. Contributions should maintain simplicity and focus on the core use case while following the established patterns.
## 📄 **License**
MIT License - see LICENSE file for details.