Contributing to GuestKit
Thank you for your interest in contributing to GuestKit! This document provides guidelines and information for contributors.
Table of Contents
- Code of Conduct
- Getting Started
- Development Setup
- Project Structure
- Coding Standards
- Testing
- Documentation
- Submitting Changes
- Adding New APIs
Code of Conduct
This project follows the Rust Code of Conduct. Please be respectful and constructive in all interactions.
Getting Started
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/guestkit.gitcd guestkit
- Add upstream remote:
git remote add upstream https://github.com/zyvorai/guestkit.git
Development Setup
Prerequisites
- Rust 1.70 or later
- System dependencies:
- qemu-img (for disk operations)
- qemu-nbd (for NBD mounting)
- cryptsetup (for LUKS support)
- lvm2 (for LVM operations)
Installation
# Install system dependencies (Fedora/RHEL)
sudo dnf install qemu-img cryptsetup lvm2
# Build the project
cargo build
# Run tests
cargo test
# Build documentation
cargo doc --open
Project Structure
guestkit/
├── src/
│ ├── lib.rs # Library root
│ ├── core/ # Core types and utilities
│ │ ├── error.rs # Error types
│ │ ├── retry.rs # Retry logic
│ │ └── mod.rs
│ ├── disk/ # Low-level disk access
│ │ ├── reader.rs # Disk reader
│ │ ├── format.rs # Format detection
│ │ └── mod.rs
│ └── guestfs/ # GuestFS-compatible API
│ ├── handle.rs # Main Guestfs struct
│ ├── mount.rs # Mount operations
│ ├── file_ops.rs # File operations
│ ├── archive.rs # Archive operations
│ ├── luks.rs # LUKS encryption
│ ├── lvm.rs # LVM management
│ ├── filesystem.rs # Filesystem operations
│ ├── partition.rs # Partition management
│ ├── inspect.rs # OS detection
│ └── ... (73+ modules)
├── examples/ # Example programs
├── tests/ # Integration tests
└── docs/ # Additional documentation
Coding Standards
Rust Style
- Follow the Rust API Guidelines
- Use
cargo fmtto format code - Use
cargo clippyto catch common mistakes - Write idiomatic Rust code
Code Organization
- Modules should be focused: Each module should handle a specific area of functionality
- Functions should be small: Aim for functions under 50 lines when possible
- Error handling: Use
Result<T, Error>for fallible operations - Documentation: Every public function must have documentation
Naming Conventions
-
Functions: Use snake_case, be descriptive
- Good:
inspect_get_hostname(),luks_open() - Bad:
get_hn(),open()
- Good:
-
Structs: Use PascalCase
- Good:
Guestfs,DiskReader - Bad:
guestfs,disk_reader
- Good:
-
Constants: Use SCREAMING_SNAKE_CASE
- Good:
MAX_RETRIES,DEFAULT_TIMEOUT
- Good:
Comments
// Use single-line comments for brief explanations
/// Use doc comments for public APIs
///
/// # Arguments
///
/// * `device` - The device path (e.g., "/dev/sda1")
/// * `format` - The filesystem format (e.g., "ext4", "xfs")
///
/// # Returns
///
/// Returns `Ok(())` on success
///
/// # Errors
///
/// Returns an error if the filesystem creation fails
///
/// # Example
///
/// ```no_run
/// # use guestkit::Guestfs;
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut g = Guestfs::new()?;
/// g.mkfs("ext4", "/dev/sda1")?;
/// # Ok(())
/// # }
/// ```
pub fn mkfs(&mut self, fstype: &str, device: &str) -> Result<()> {
// Implementation
}
Testing
Running Tests
# Run all tests
cargo test
# Run specific test
cargo test test_name
# Run tests with output
cargo test -- --nocapture
# Run integration tests only
cargo test --test '*'
Writing Tests
-
Unit tests: Place in the same file as the code
#[cfg(test)]mod tests {use super::*;#[test]fn test_function() {assert_eq!(2 + 2, 4);}} -
Integration tests: Place in
tests/directory// tests/integration_test.rsuse guestkit::Guestfs;#[test]fn test_workflow() -> Result<(), Box<dyn std::error::Error>> {let mut g = Guestfs::new()?;// Test codeOk(())} -
Example tests: Examples in
examples/should compilecargo test --examples
Test Coverage
- Aim for at least 70% code coverage
- All public APIs should have tests
- Test both success and error cases
Documentation
Documentation Requirements
- Public APIs: Must have doc comments
- Modules: Should have module-level documentation
- Examples: Complex functions should have usage examples
- Error conditions: Document when errors occur
Building Documentation
# Build and open documentation
cargo doc --open
# Build documentation with private items
cargo doc --document-private-items
Documentation Style
//! Module-level documentation goes here
//!
//! This module provides...
/// Brief one-line summary
///
/// More detailed explanation can go here. Explain what
/// the function does, any important details, etc.
///
/// # Arguments
///
/// * `param1` - Description of first parameter
/// * `param2` - Description of second parameter
///
/// # Returns
///
/// Description of return value
///
/// # Errors
///
/// Describe error conditions
///
/// # Examples
///
/// ```no_run
/// # use guestkit::Guestfs;
/// let mut g = Guestfs::new()?;
/// g.some_function("param")?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn some_function(&mut self, param1: &str) -> Result<String> {
// Implementation
}
Submitting Changes
Commit Messages
Write clear, descriptive commit messages:
Short summary (50 chars or less)
More detailed explanation if needed. Wrap at 72 characters.
Explain what changed and why, not how.
- Bullet points are okay
- Use present tense: "Add feature" not "Added feature"
- Reference issues: "Fixes #123"
Examples:
Add support for btrfs subvolume operations
Implement create, delete, and list operations for btrfs
subvolumes. Adds new module src/guestfs/btrfs.rs with
comprehensive subvolume management.
Fixes #45
Pull Request Process
- Update documentation: Ensure docs are updated
- Add tests: New features must have tests
- Run checks:
cargo fmt --checkcargo clippycargo testcargo build --release
- Update CHANGELOG.md: Add entry for your changes
- Create pull request: With clear description
- Address review comments: Make requested changes
Pull Request Template
## Description
Brief description of changes
## Motivation
Why is this change needed?
## Changes
- List of specific changes
- Another change
## Testing
How has this been tested?
## Checklist
- [ ] Tests pass (`cargo test`)
- [ ] Code formatted (`cargo fmt`)
- [ ] No clippy warnings (`cargo clippy`)
- [ ] Documentation updated
- [ ] CHANGELOG.md updated
- [ ] Examples added/updated if needed
Adding New APIs
Adding a New Module
- Create the module file:
src/guestfs/newmodule.rs
// SPDX-License-Identifier: Apache-2.0
//! Brief module description
//!
//! Detailed module documentation
use crate::core::{Error, Result};
use crate::guestfs::Guestfs;
use std::process::Command;
impl Guestfs {
/// Brief function description
///
/// Detailed documentation
pub fn new_operation(&mut self, param: &str) -> Result<String> {
self.ensure_ready()?;
if self.verbose {
eprintln!("guestfs: new_operation {}", param);
}
// Implementation
let output = Command::new("some_tool")
.arg(param)
.output()
.map_err(|e| Error::CommandFailed(format!("Failed: {}", e)))?;
if !output.status.success() {
return Err(Error::CommandFailed(
String::from_utf8_lossy(&output.stderr).to_string()
));
}
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_operation_api() {
let mut g = Guestfs::new().unwrap();
// Basic API test
}
}
- Register the module: Add to
src/guestfs/mod.rs
pub mod newmodule;
-
Update documentation: Add to
GUESTFS_IMPLEMENTATION_STATUS.md -
Add example: Create
examples/newmodule_example.rs -
Run tests:
cargo test
cargo check
Compatibility
When implementing -compatible APIs:
- Match function signatures as closely as possible
- Use same parameter names for clarity
- Preserve behavior - match semantics
- Document differences - note any deviations
Error Handling
Use the standard error types:
use crate::core::Error;
// Command execution failed
Err(Error::CommandFailed(format!("Command failed: {}", e)))
// File system error
Err(Error::FileSystem(format!("Mount failed: {}", e)))
// Not ready error
Err(Error::NotReady("Must call launch() first".into()))
// Invalid input
Err(Error::InvalidInput(format!("Invalid device: {}", device)))
Additional Resources
- API Reference - Complete API documentation
- Implementation Status - Current status
- Examples - Example programs
- documentation - Upstream reference
Questions?
- Open an issue on GitHub
- Check existing issues and discussions
- Read the documentation
License
By contributing, you agree that your contributions will be licensed under the Apache-2.0 license and that ZyvorAI Labs Private Limited may include them in GuestKit.