apt-tx/docs/rollbacks.md
robojerk 2daad2837d Major improvements: rollbacks, testing, docs, and code quality
- Fixed rollback implementation with two-phase approach (remove new, downgrade upgraded)
- Added explicit package tracking (newly_installed vs upgraded)
- Implemented graceful error handling with fail-fast approach
- Added comprehensive test suite (20 tests across 3 test files)
- Created centralized APT command execution module (apt_commands.rs)
- Added configuration system with dry-run, quiet, and APT options
- Reduced code duplication and improved maintainability
- Added extensive documentation (rollbacks.md, rollbacks-not-featured.md, ffi-bridge.md)
- Created configuration usage example
- Updated README with crate usage instructions
- All tests passing, clean compilation, production-ready
2025-09-13 11:21:35 -07:00

2.8 KiB

Rollback Implementation

This document explains how the rollback functionality works in the APT wrapper.

Overview

The rollback system provides a simple way to undo package installations and upgrades. It tracks what packages were changed during a transaction and can restore the system to its previous state.

How It Works

Package Tracking

The AptTransaction struct tracks two types of package changes:

  • newly_installed: Packages that weren't installed before the transaction
  • upgraded: Packages that were upgraded, with their previous versions stored

Two-Phase Rollback

When rollback() is called, it performs two phases:

  1. Phase 1 - Remove New Packages: Uses apt remove -y to remove all packages in newly_installed
  2. Phase 2 - Downgrade Upgraded Packages: Uses apt install -y package=oldversion to restore previous versions

Example Usage

use apt_wrapper::AptTransaction;

// Create and commit a transaction
let mut tx = AptTransaction::new()?;
tx.add_package("vim")?;
tx.add_package("curl")?;
tx.commit()?;

// Later, rollback the changes
tx.rollback()?;

Error Handling

The rollback system uses a "fail fast" approach:

  • Critical errors (package not found, permission denied) cause immediate failure
  • Soft errors (package already removed) generate warnings but continue
  • If a specific version can't be installed, the package is removed instead

Limitations

This implementation is intentionally simple and handles the most common rollback scenarios:

  • New package installations
  • Package upgrades with available previous versions
  • Mixed transactions (some new, some upgrades)

It does not handle:

  • Complex dependency changes
  • Configuration file modifications
  • System state beyond package versions
  • Concurrent package operations

For more advanced rollback scenarios, see rollbacks-not-featured.md.

Implementation Details

Data Structures

pub struct AptTransaction {
    packages: Vec<String>,
    newly_installed: HashSet<String>,  // packages that weren't installed before
    upgraded: HashMap<String, String>, // package -> old_version for upgrades
}

Key Methods

  • add_package(): Adds a package to the transaction
  • commit(): Installs packages and categorizes them as new vs upgraded
  • rollback(): Performs the two-phase rollback process
  • changed_packages(): Returns a list of what was changed

State Management

The tracking fields (newly_installed, upgraded) are only populated after a successful commit(). This ensures the rollback data reflects what actually happened during the transaction.

Testing

The rollback functionality is tested in the test suite, but actual package installation/removal is not performed in tests to avoid side effects on the test environment.