- Add docs/README.md with project overview and current status - Add docs/architecture.md with detailed architecture documentation - Add docs/development.md with development guide for contributors - Update .notes/todo.md to reflect architecture fix completion - Update .notes/plan.md with completed phases and next priorities Architecture fixes (daemon and dbus), bubblewrap integration are now complete. Ready for OCI integration phase.
11 KiB
11 KiB
apt-ostree Development Guide
Development Environment Setup
Prerequisites
# Install Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Install system dependencies
sudo apt update
sudo apt install -y \
build-essential \
pkg-config \
libostree-dev \
libapt-pkg-dev \
bubblewrap \
dbus \
systemd \
clang \
libclang-dev
# Install additional development tools
sudo apt install -y \
cargo-watch \
cargo-audit \
cargo-tarpaulin \
rustfmt \
clippy
Project Setup
# Clone repository
git clone https://github.com/your-org/apt-ostree.git
cd apt-ostree
# Install Rust dependencies
cargo build
# Run tests
cargo test
# Check code quality
cargo fmt --check
cargo clippy
cargo audit
Project Structure
apt-ostree/
├── src/
│ ├── main.rs # CLI application entry point
│ ├── lib.rs # Library interface
│ ├── daemon_client.rs # D-Bus client library
│ ├── system.rs # System integration
│ ├── apt.rs # APT package management
│ ├── ostree.rs # OSTree operations
│ ├── bubblewrap_sandbox.rs # Script sandboxing
│ ├── package_manager.rs # High-level package operations
│ ├── permissions.rs # Permission handling
│ ├── error.rs # Error types
│ └── bin/
│ └── apt-ostreed.rs # D-Bus daemon
├── src/daemon/ # Daemon configuration files
│ ├── apt-ostreed.service # systemd service file
│ ├── org.aptostree.dev.conf # D-Bus policy
│ └── org.aptostree.dev.service # D-Bus activation
├── docs/ # Documentation
├── tests/ # Integration tests
├── scripts/ # Build and deployment scripts
└── .notes/ # Development notes and research
Architecture Overview
Daemon-Client Model
apt-ostree follows the same daemon-client architecture as rpm-ostree:
┌─────────────────┐ D-Bus ┌─────────────────┐
│ apt-ostree │ ──────────► │ apt-ostreed │
│ (Client) │ │ (Daemon) │
└─────────────────┘ └─────────────────┘
│ │
│ Fallback │
▼ │
┌─────────────────┐ │
│ AptOstreeSystem │ │
│ (Client-only) │ │
└─────────────────┘ │
│
▼
┌─────────────────┐
│ OSTree/APT │
│ Operations │
└─────────────────┘
Key Components
Client (src/main.rs)
- Command-line interface and argument parsing
- D-Bus communication with daemon
- Fallback to client-only operations
- Output formatting and error handling
Daemon (src/bin/apt-ostreed.rs)
- D-Bus interface implementation
- Privileged system operations
- Transaction management
- OSTree and APT integration
Daemon Client (src/daemon_client.rs)
- D-Bus communication library
- Method call abstractions
- Error handling and retry logic
- Connection management
Development Workflow
Adding New Commands
- Define Command Structure
// In src/main.rs
#[derive(Subcommand)]
enum Commands {
// ... existing commands ...
/// New command description
NewCommand {
/// Command argument
arg: String,
/// Optional flag
#[arg(long)]
flag: bool,
},
}
- Implement Command Logic
// In src/main.rs match statement
Commands::NewCommand { arg, flag } => {
let result = call_daemon_with_fallback(
|client| Box::pin(client.new_command(arg.clone(), flag)),
|| Box::pin(async {
// Fallback implementation
let system = AptOstreeSystem::new("debian/stable/x86_64").await?;
system.new_command(&arg, flag).await?;
Ok("Command completed successfully".to_string())
})
).await?;
println!("{}", result);
}
- Add Daemon Method
// In src/bin/apt-ostreed.rs
#[dbus_interface(name = "org.aptostree.dev.Daemon")]
impl AptOstreeDaemon {
async fn new_command(&self, arg: String, flag: bool) -> zbus::fdo::Result<String> {
// Implementation
Ok("Command result".to_string())
}
}
- Add Client Method
// In src/daemon_client.rs
impl DaemonClient {
pub async fn new_command(&self, arg: String, flag: bool) -> Result<String, Box<dyn Error>> {
let reply: String = self.proxy.call("new_command", &(arg, flag)).await?;
Ok(reply)
}
}
Adding New Modules
- Create Module File
// src/new_module.rs
use crate::error::{AptOstreeError, AptOstreeResult};
pub struct NewModule {
// Module state
}
impl NewModule {
pub fn new() -> AptOstreeResult<Self> {
Ok(Self {})
}
pub async fn do_something(&self) -> AptOstreeResult<()> {
// Implementation
Ok(())
}
}
- Add to lib.rs
// src/lib.rs
pub mod new_module;
- Add Tests
// src/new_module.rs
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_new_module() {
let module = NewModule::new().unwrap();
assert!(module.do_something().await.is_ok());
}
}
Testing
Unit Tests
# Run all tests
cargo test
# Run specific test
cargo test test_name
# Run tests with output
cargo test -- --nocapture
# Run tests in parallel
cargo test -- --test-threads=1
Integration Tests
# Run integration tests
cargo test --test integration_tests
# Run with daemon
sudo systemctl start apt-ostreed
cargo test --test daemon_tests
Architecture Tests
# Test daemon communication
./test-architecture.sh
# Test command fallback
sudo systemctl stop apt-ostreed
apt-ostree status
Performance Tests
# Run benchmarks
cargo bench
# Profile performance
cargo install flamegraph
cargo flamegraph --bin apt-ostree -- install nginx
Code Quality
Formatting
# Format code
cargo fmt
# Check formatting
cargo fmt --check
Linting
# Run clippy
cargo clippy
# Run clippy with all warnings
cargo clippy -- -W clippy::all
# Run clippy with pedantic warnings
cargo clippy -- -W clippy::pedantic
Security
# Check for security vulnerabilities
cargo audit
# Update dependencies
cargo update
Documentation
# Generate documentation
cargo doc
# Generate and open documentation
cargo doc --open
# Check documentation
cargo doc --no-deps
Debugging
Debug Build
# Build with debug symbols
cargo build
# Run with debug logging
RUST_LOG=debug cargo run --bin apt-ostree -- status
Daemon Debugging
# Run daemon in foreground
RUST_LOG=debug cargo run --bin apt-ostreed
# Check daemon logs
sudo journalctl -u apt-ostreed -f
# Test D-Bus interface
d-feet # GUI D-Bus browser
gdbus introspect --system --dest org.aptostree.dev --object-path /org/aptostree/dev
D-Bus Debugging
# Monitor D-Bus traffic
dbus-monitor --system
# Test D-Bus method calls
gdbus call --system --dest org.aptostree.dev --object-path /org/aptostree/dev/Daemon --method org.aptostree.dev.Daemon.ping
Building and Installing
Development Build
# Build development version
cargo build
# Install development version
sudo cp target/debug/apt-ostree /usr/bin/
sudo cp target/debug/apt-ostreed /usr/libexec/
Release Build
# Build release version
cargo build --release
# Install release version
sudo cp target/release/apt-ostree /usr/bin/
sudo cp target/release/apt-ostreed /usr/libexec/
Complete Installation
# Run installation script
sudo ./apt-ostree-complete-fix.sh
# Verify installation
sudo apt-ostree daemon-ping
apt-ostree status
Contributing Guidelines
Code Style
- Rust Conventions: Follow Rust coding conventions
- Documentation: Document all public APIs
- Error Handling: Use proper error types and handling
- Testing: Write tests for new functionality
- Logging: Use appropriate log levels
Commit Messages
type(scope): description
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changesrefactor: Code refactoringtest: Test changeschore: Build/tooling changes
Pull Request Process
- Fork Repository: Create personal fork
- Create Branch: Create feature branch
- Make Changes: Implement changes with tests
- Run Tests: Ensure all tests pass
- Submit PR: Create pull request with description
- Code Review: Address review comments
- Merge: Merge after approval
Issue Reporting
When reporting issues, include:
- System Information: OS, version, architecture
- Reproduction Steps: Clear steps to reproduce
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Logs: Relevant error messages and logs
- Environment: Development or production environment
Performance Optimization
Profiling
# CPU profiling
cargo install cargo-profiler
cargo profiler callgrind --bin apt-ostree -- install nginx
# Memory profiling
cargo install cargo-valgrind
cargo valgrind memcheck --bin apt-ostree -- install nginx
Benchmarking
# Run benchmarks
cargo bench
# Compare benchmarks
cargo bench --bench compare
Optimization Tips
- Async Operations: Use async/await for I/O operations
- Parallel Processing: Use parallel iterators where appropriate
- Memory Management: Minimize allocations and use efficient data structures
- Caching: Cache expensive operations
- Streaming: Use streaming for large files
Troubleshooting
Common Issues
Build Failures
# Clean and rebuild
cargo clean
cargo build
# Check dependencies
cargo tree
cargo update
Test Failures
# Run specific test
cargo test test_name
# Run with verbose output
cargo test -- --nocapture
# Check test environment
cargo test -- --list
Daemon Issues
# Check daemon status
sudo systemctl status apt-ostreed
# Restart daemon
sudo systemctl restart apt-ostreed
# Check logs
sudo journalctl -u apt-ostreed -f
D-Bus Issues
# Check D-Bus service
gdbus introspect --system --dest org.aptostree.dev
# Restart D-Bus
sudo systemctl restart dbus
# Check D-Bus policy
sudo cat /etc/dbus-1/system.d/org.aptostree.dev.conf
Getting Help
- Check Documentation: Review this guide and other docs
- Search Issues: Look for similar issues in the repository
- Ask Questions: Create issue with question label
- Join Community: Participate in discussions and forums