# Deb-Mock Plugin System ## Overview The deb-mock plugin system provides a powerful and extensible way to customize build behavior, add new features, and integrate with external tools. It's based on Fedora Mock's proven plugin architecture, adapted specifically for Debian-based build environments. ## Features - **Hook-based architecture** - Plugins can hook into various stages of the build process - **Dynamic loading** - Plugins are loaded at runtime based on configuration - **API versioning** - Ensures compatibility between deb-mock versions and plugins - **Configuration-driven** - Rich configuration options for each plugin - **Error handling** - Robust error handling with required vs. optional plugins - **Base classes** - Helper classes for easier plugin development ## Architecture ### Core Components 1. **PluginManager** - Main plugin orchestration class 2. **HookStages** - Standard hook stages for plugins 3. **BasePlugin** - Base class for plugin development 4. **Plugin Configuration** - YAML-based plugin configuration ### Hook Stages The plugin system provides hooks at various stages of the build process: #### Chroot Lifecycle - `prechroot_init` - Before chroot initialization - `postchroot_init` - After chroot initialization - `prechroot_clean` - Before chroot cleanup - `postchroot_clean` - After chroot cleanup #### Build Lifecycle - `prebuild` - Before build starts - `postbuild` - After build completes - `build_start` - When build begins - `build_end` - When build ends #### Package Management - `pre_install_deps` - Before installing dependencies - `post_install_deps` - After installing dependencies - `pre_install_package` - Before installing packages - `post_install_package` - After installing packages #### Mount Management - `pre_mount` - Before mounting filesystems - `post_mount` - After mounting filesystems - `pre_unmount` - Before unmounting filesystems - `post_unmount` - After unmounting filesystems #### Cache Management - `pre_cache_create` - Before creating caches - `post_cache_create` - After creating caches - `pre_cache_restore` - Before restoring caches - `post_cache_restore` - After restoring caches #### Parallel Build Hooks - `pre_parallel_build` - Before parallel builds - `post_parallel_build` - After parallel builds - `parallel_build_start` - When parallel build starts - `parallel_build_end` - When parallel build ends #### Error Handling - `on_error` - When errors occur - `on_warning` - When warnings occur ## Configuration ### Basic Plugin Configuration ```yaml # Enable plugins plugins: ["ccache_plugin", "build_monitor"] # Plugin directory (optional) plugin_dir: "./plugins" # Plugin-specific configuration plugin_conf: # CCache plugin ccache_enable: true ccache_required: false ccache_opts: dir: "/var/cache/deb-mock/ccache" max_cache_size: "4G" show_stats: true compress: true hashdir: true debug: false # Build monitor plugin build_monitor_enable: true build_monitor_required: false build_monitor_opts: log_file: "/var/log/deb-mock/builds.log" notify_on_completion: true track_build_time: true ``` ### Plugin Configuration Options - **`{plugin}_enable`** - Enable/disable plugin (default: true) - **`{plugin}_required`** - Make plugin required (default: false) - **`{plugin}_opts`** - Plugin-specific configuration options ## Plugin Development ### Basic Plugin Structure ```python #!/usr/bin/env python3 """ Example plugin for deb-mock """ requires_api_version = "1.0" run_in_bootstrap = False def init(plugin_manager, conf, deb_mock): """Plugin entry point""" ExamplePlugin(plugin_manager, conf, deb_mock) class ExamplePlugin: """Example plugin implementation""" def __init__(self, plugin_manager, conf, deb_mock): self.plugin_manager = plugin_manager self.conf = conf self.deb_mock = deb_mock # Register hooks self._register_hooks() def _register_hooks(self): """Register plugin hooks""" self.plugin_manager.add_hook("prebuild", self._prebuild_hook) self.plugin_manager.add_hook("postbuild", self._postbuild_hook) def _prebuild_hook(self, source_package, **kwargs): """Hook called before build starts""" print(f"Example plugin: Pre-build hook for {source_package}") def _postbuild_hook(self, build_result, source_package, **kwargs): """Hook called after build completes""" print(f"Example plugin: Post-build hook for {source_package}") ``` ### Using BasePlugin Class ```python from deb_mock.plugin import BasePlugin, HookStages class MyPlugin(BasePlugin): """Plugin using the base class""" def _register_hooks(self): """Override to register hooks""" self.plugin_manager.add_hook(HookStages.PREBUILD, self._my_hook) def _my_hook(self, source_package, **kwargs): """My custom hook""" self.log_info(f"Processing {source_package}") # Plugin logic here ``` ### Plugin API Requirements Every plugin must define: 1. **`requires_api_version`** - API version compatibility 2. **`run_in_bootstrap`** - Whether to run in bootstrap chroots 3. **`init()` function** - Plugin entry point ### Available Hooks Plugins can register hooks for any of the standard stages defined in `HookStages`, or create custom stages. ## Built-in Plugins ### CCache Plugin The CCache plugin provides compiler caching for faster rebuilds: ```yaml plugin_conf: ccache_enable: true ccache_opts: dir: "/var/cache/deb-mock/ccache" max_cache_size: "4G" show_stats: true compress: true hashdir: true debug: false ``` **Features:** - Automatic ccache setup in chroots - Configurable cache size and options - Build statistics reporting - Environment variable management ### Build Monitor Plugin The Build Monitor plugin tracks build performance and provides notifications: ```yaml plugin_conf: build_monitor_enable: true build_monitor_opts: log_file: "/var/log/deb-mock/builds.log" notify_on_completion: true track_build_time: true performance_metrics: true ``` **Features:** - Build time tracking - Performance metrics collection - Completion notifications - Detailed logging ## CLI Commands ### Plugin Management ```bash # Show plugin information deb-mock plugin-info # List available hook stages deb-mock list-stages # List hooks for a specific stage deb-mock list-hooks prebuild ``` ### Plugin Configuration Plugins are configured through the main configuration file or command-line options. The plugin system automatically loads enabled plugins and initializes them with the deb-mock instance. ## Best Practices ### Plugin Development 1. **Use descriptive names** - Choose clear, descriptive plugin names 2. **Handle errors gracefully** - Don't let plugin failures break builds 3. **Use logging** - Use the provided logging methods for debugging 4. **Validate configuration** - Check configuration values and provide defaults 5. **Document hooks** - Clearly document what each hook does ### Configuration 1. **Enable only needed plugins** - Don't enable plugins you don't use 2. **Use required sparingly** - Only mark plugins as required if builds fail without them 3. **Provide defaults** - Always provide sensible default values 4. **Test configurations** - Test plugin configurations before production use ### Performance 1. **Minimize hook overhead** - Keep hooks lightweight 2. **Use async when possible** - Consider async operations for I/O heavy tasks 3. **Cache results** - Cache expensive operations when appropriate 4. **Profile plugins** - Monitor plugin performance impact ## Troubleshooting ### Common Issues 1. **Plugin not loading** - Check plugin directory and file permissions 2. **API version mismatch** - Ensure plugin API version matches deb-mock 3. **Hook not firing** - Verify hook stage names and registration 4. **Configuration errors** - Check YAML syntax and plugin configuration ### Debugging 1. **Enable debug logging** - Use `--debug` flag for verbose output 2. **Check plugin info** - Use `plugin-info` command to verify plugin loading 3. **Verify hooks** - Use `list-hooks` to check hook registration 4. **Test individually** - Test plugins in isolation before integration ## Examples ### Complete Plugin Example See `examples/plugins/ccache_plugin.py` for a complete working plugin. ### Configuration Example See `examples/plugin-config.yaml` for a complete plugin-enabled configuration. ## API Reference ### PluginManager Methods - `init_plugins(deb_mock)` - Initialize all enabled plugins - `call_hooks(stage, *args, **kwargs)` - Call hooks for a stage - `add_hook(stage, function)` - Register a hook function - `remove_hook(stage, function)` - Remove a hook function - `get_hooks(stage)` - Get hooks for a stage - `list_stages()` - List available hook stages - `get_plugin_info()` - Get plugin system information ### BasePlugin Methods - `get_config(key, default)` - Get plugin configuration - `set_config(key, value)` - Set plugin configuration - `log_info(message)` - Log info message - `log_warning(message)` - Log warning message - `log_error(message)` - Log error message - `log_debug(message)` - Log debug message ## Future Enhancements - **Plugin repositories** - Centralized plugin distribution - **Plugin dependencies** - Plugin-to-plugin dependencies - **Plugin validation** - Automated plugin testing and validation - **Plugin metrics** - Performance and usage metrics - **Plugin hot-reload** - Runtime plugin updates