deb-mock/docs/API.md
robojerk 8c585e2e33
Some checks failed
Build Deb-Mock Package / build (push) Failing after 59s
Lint Code / Lint All Code (push) Failing after 2s
Test Deb-Mock Build / test (push) Failing after 41s
Add stable Python API and comprehensive environment management
- Add MockAPIClient and MockEnvironment for external integration
- Implement EnvironmentManager with full lifecycle support
- Enhance plugin system with registry and BasePlugin class
- Add comprehensive test suite and documentation
- Include practical usage examples and plugin development guide
2025-09-04 10:04:16 -07:00

12 KiB

deb-mock API Documentation

This document provides comprehensive documentation for the deb-mock Python API, designed for external tools and integrations.

Table of Contents

Quick Start

from deb_mock import create_client, MockConfigBuilder

# Create a configuration
config = (MockConfigBuilder()
          .environment("my-build-env")
          .architecture("amd64")
          .suite("trixie")
          .packages(["build-essential", "cmake"])
          .build())

# Create API client
client = create_client(config)

# Create environment
env = client.create_environment("my-build-env")

# Use environment
with client.environment("my-build-env") as env:
    env.install_packages(["ninja-build"])
    result = env.execute(["cmake", "--version"])
    print(f"CMake version: {result.stdout}")

# Build a package
result = client.build_package("/path/to/package.dsc", "my-build-env")
print(f"Build successful: {result['success']}")

API Overview

The deb-mock API consists of several main components:

Core Classes

  • MockAPIClient: Main API client for high-level operations
  • MockEnvironment: Represents a mock environment
  • EnvironmentManager: Comprehensive environment management
  • MockConfigBuilder: Fluent configuration builder

Data Classes

  • EnvironmentInfo: Information about a mock environment
  • BuildResult: Result of a build operation

Convenience Functions

  • create_client(): Create a new API client
  • create_config(): Create a configuration builder
  • quick_build(): Quick build function for simple use cases

Configuration

Using MockConfigBuilder

The MockConfigBuilder provides a fluent interface for creating configurations:

from deb_mock import MockConfigBuilder

config = (MockConfigBuilder()
          .environment("debian-trixie-amd64")
          .architecture("amd64")
          .suite("trixie")
          .mirror("http://deb.debian.org/debian/")
          .packages(["build-essential", "devscripts"])
          .output_dir("/tmp/build-output")
          .cache_enabled(True)
          .parallel_jobs(4)
          .verbose(True)
          .build())

Configuration Options

Method Description Default
.environment(name) Environment name "bookworm-amd64"
.architecture(arch) Target architecture "amd64"
.suite(suite) Debian suite "bookworm"
.mirror(url) Package mirror URL Debian official
.packages(list) Initial packages to install []
.output_dir(path) Output directory "./output"
.cache_enabled(bool) Enable caching True
.parallel_jobs(int) Number of parallel jobs 4
.verbose(bool) Verbose output False
.debug(bool) Debug output False

Direct Configuration

You can also create configurations directly:

from deb_mock import Config

config = Config(
    chroot_name="my-env",
    architecture="amd64",
    suite="trixie",
    mirror="http://deb.debian.org/debian/",
    chroot_additional_packages=["build-essential"],
    use_root_cache=True,
    parallel_jobs=4
)

Environment Management

Creating Environments

from deb_mock import create_client

client = create_client()

# Create environment with specific settings
env = client.create_environment(
    name="build-env",
    arch="amd64",
    suite="trixie",
    packages=["build-essential", "cmake"]
)

Environment Information

# Get environment info
info = env.get_info()
print(f"Environment: {info.name}")
print(f"Architecture: {info.architecture}")
print(f"Suite: {info.suite}")
print(f"Status: {info.status}")

Listing Environments

# List all environments
environments = client.list_environments()
for env_name in environments:
    print(f"Environment: {env_name}")

Removing Environments

# Remove environment
client.remove_environment("build-env")

Command Execution

Basic Command Execution

# Execute a command
result = env.execute(["ls", "-la", "/usr/bin"])
print(f"Return code: {result.returncode}")
print(f"Output: {result.stdout}")

# Execute string command
result = env.execute("dpkg -l | grep build-essential")

Command Options

# Execute with options
result = env.execute(
    ["apt", "list", "--installed"],
    capture_output=True,
    check=True,
    timeout=30
)

Using Environment Manager

from deb_mock import create_environment_manager

manager = create_environment_manager()

# Execute command in environment
result = manager.execute_command(
    "build-env",
    ["cmake", "--version"],
    capture_output=True
)

Package Building

Building Single Packages

# Build a package
result = client.build_package(
    source_package="/path/to/package.dsc",
    environment="build-env",
    output_dir="/tmp/build-output"
)

print(f"Build successful: {result['success']}")
print(f"Artifacts: {result['artifacts']}")

Parallel Building

# Build multiple packages in parallel
packages = [
    "/path/to/package1.dsc",
    "/path/to/package2.dsc",
    "/path/to/package3.dsc"
]

results = client.build_parallel(
    packages,
    max_workers=2
)

for i, result in enumerate(results):
    print(f"Package {i+1}: {'Success' if result['success'] else 'Failed'}")

Chain Building

# Build packages in dependency order
chain = [
    "/path/to/base-package.dsc",
    "/path/to/depends-on-base.dsc",
    "/path/to/final-package.dsc"
]

results = client.build_chain(chain)

Advanced Features

Context Managers

# Use environment context manager
with client.environment("build-env") as env:
    env.install_packages(["cmake", "ninja-build"])
    result = env.execute(["cmake", "--version"])
    # Environment is automatically cleaned up

File Operations

# Copy files into environment
env.copy_in("/local/source", "/build/source")

# Copy files out of environment
env.copy_out("/build/artifacts", "/local/artifacts")

Artifact Collection

from deb_mock import create_environment_manager

manager = create_environment_manager()

# Collect build artifacts
artifacts = manager.collect_artifacts(
    "build-env",
    source_patterns=["*.deb", "*.changes"],
    output_dir="/tmp/artifacts"
)

print(f"Collected {len(artifacts)} artifacts")

Performance Monitoring

# Get cache statistics
cache_stats = client.get_cache_stats()
print(f"Cache stats: {cache_stats}")

# Get performance summary
perf_summary = client.get_performance_summary()
print(f"Performance: {perf_summary}")

# Export metrics
metrics_file = client.export_metrics("/tmp/metrics.json")
print(f"Metrics exported to: {metrics_file}")

Error Handling

Common Exceptions

from deb_mock.exceptions import ChrootError, ConfigurationError, SbuildError

try:
    env = client.create_environment("test-env")
except ChrootError as e:
    print(f"Chroot error: {e}")
except ConfigurationError as e:
    print(f"Configuration error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Environment Validation

# Check if environment exists
if client.environment_exists("test-env"):
    print("Environment exists")
else:
    print("Environment does not exist")

Command Error Handling

# Execute command with error handling
result = env.execute(["invalid-command"], check=False)
if result.returncode != 0:
    print(f"Command failed: {result.stderr}")

Examples

Complete Build Workflow

from deb_mock import create_client, MockConfigBuilder

# Create configuration
config = (MockConfigBuilder()
          .environment("build-env")
          .architecture("amd64")
          .suite("trixie")
          .packages(["build-essential", "devscripts", "cmake"])
          .cache_enabled(True)
          .parallel_jobs(4)
          .build())

# Create client
client = create_client(config)

try:
    # Create environment
    env = client.create_environment("build-env")
    
    # Use environment
    with client.environment("build-env") as env:
        # Install additional packages
        env.install_packages(["ninja-build", "git"])
        
        # Execute setup commands
        env.execute(["git", "clone", "https://github.com/example/project.git", "/build/project"])
        
        # Build the package
        result = client.build_package("/build/project", "build-env")
        
        if result['success']:
            print("Build successful!")
            print(f"Artifacts: {result['artifacts']}")
        else:
            print("Build failed!")
    
finally:
    # Cleanup
    client.remove_environment("build-env")

Multi-Architecture Building

architectures = ["amd64", "arm64", "armhf"]
packages = ["/path/to/package.dsc"]

for arch in architectures:
    config = (MockConfigBuilder()
              .environment(f"build-{arch}")
              .architecture(arch)
              .suite("trixie")
              .build())
    
    client = create_client(config)
    
    try:
        env = client.create_environment(f"build-{arch}")
        result = client.build_package("/path/to/package.dsc", f"build-{arch}")
        print(f"{arch}: {'Success' if result['success'] else 'Failed'}")
    finally:
        client.remove_environment(f"build-{arch}")

CI/CD Integration

import os
from deb_mock import create_client, MockConfigBuilder

def build_package_in_ci(source_package, arch="amd64", suite="trixie"):
    """Build package in CI environment"""
    
    # Create configuration from environment variables
    config = (MockConfigBuilder()
              .environment(f"ci-build-{arch}")
              .architecture(arch)
              .suite(suite)
              .mirror(os.getenv("DEBIAN_MIRROR", "http://deb.debian.org/debian/"))
              .packages(["build-essential", "devscripts"])
              .output_dir(os.getenv("BUILD_OUTPUT_DIR", "/tmp/build-output"))
              .build())
    
    client = create_client(config)
    
    try:
        # Create environment
        env = client.create_environment(f"ci-build-{arch}")
        
        # Build package
        result = client.build_package(source_package, f"ci-build-{arch}")
        
        return {
            'success': result['success'],
            'artifacts': result['artifacts'],
            'environment': f"ci-build-{arch}"
        }
    
    finally:
        # Cleanup
        client.remove_environment(f"ci-build-{arch}")

# Usage in CI
if __name__ == "__main__":
    result = build_package_in_ci("/workspace/package.dsc")
    if result['success']:
        print("CI build successful!")
    else:
        print("CI build failed!")
        exit(1)

Integration with External Tools

debian-forge Integration

The deb-mock API is designed to integrate seamlessly with debian-forge:

# Example debian-forge stage using deb-mock
def debian_forge_mock_stage(tree, options):
    from deb_mock import create_client, MockConfigBuilder
    
    # Create mock configuration from debian-forge options
    mock_options = options.get('mock_options', {})
    config = (MockConfigBuilder()
              .environment(mock_options.get('environment', 'debian-trixie'))
              .architecture(mock_options.get('arch', 'amd64'))
              .suite(mock_options.get('suite', 'trixie'))
              .packages(mock_options.get('packages', []))
              .build())
    
    client = create_client(config)
    
    # Create environment
    env_name = f"{config.chroot_name}-{int(time.time())}"
    env = client.create_environment(env_name)
    
    try:
        # Execute build commands
        for command in options.get('commands', []):
            result = env.execute(command)
            if result.returncode != 0:
                raise RuntimeError(f"Command failed: {command}")
        
        # Collect artifacts
        artifacts = client.collect_artifacts(env_name, output_dir=tree)
        
        return 0
    
    finally:
        client.remove_environment(env_name)

This API provides a stable, well-documented interface for external tools to integrate with deb-mock for build environment management.