Adding an Execution Environment Plugin to PANTHER¤
Advanced Development Guide
This guide covers advanced plugin development for execution environments. Ensure you have experience with Python development, PANTHER architecture, and execution monitoring concepts before proceeding.
This guide walks through the process of creating a new execution environment plugin for the PANTHER framework.
Overview¤
Execution environment plugins provide control over the runtime context where services execute. These plugins enable resource monitoring, performance profiling, and execution control for PANTHER experiments.
Implementation Steps¤
Development Prerequisites
Before starting development, familiarize yourself with the PANTHER plugin architecture and review existing execution environment plugins like strace
or gperf_cpu
for implementation patterns.
1. Create the Plugin Directory Structure¤
Create the following directory structure for your plugin:
panther/plugins/environments/execution_environment/your_plugin_name/
├── __init__.py
├── your_plugin_name.py
├── config_schema.py
└── README.md
2. Define the Configuration Schema¤
Create a configuration schema in config_schema.py
that defines the parameters your plugin accepts:
from dataclasses import dataclass, field
from typing import Dict, List, Optional
from panther.plugins.environments.execution_environment.config_schema import ExecutionEnvironmentConfig
@dataclass
class YourPluginConfig(ExecutionEnvironmentConfig):
"""Configuration for YourPlugin execution environment."""
parameter1: str = "default_value" # Add your parameters here
parameter2: int = 100
optional_params: Dict[str, str] = field(default_factory=dict)
3. Implement the Execution Environment Class¤
Create your main plugin implementation in your_plugin_name.py
:
from abc import ABC
from panther.core.observer.event_manager import EventManager
from panther.config.config_experiment_schema import TestConfig
from panther.config.config_global_schema import GlobalConfig
from panther.plugins.environments.execution_environment.your_plugin_name.config_schema import YourPluginConfig
from panther.plugins.environments.execution_environment.execution_environment_interface import IExecutionEnvironment
from panther.plugins.plugin_loader import PluginLoader
from panther.plugins.services.services_interface import IServiceManager
class YourPluginEnvironment(IExecutionEnvironment, ABC):
"""
YourPluginEnvironment provides execution control and monitoring capabilities.
It extends the IExecutionEnvironment interface to implement specific execution features.
"""
def __init__(
self,
env_config_to_test: YourPluginConfig,
output_dir: str,
env_type: str,
env_sub_type: str,
event_manager: EventManager,
):
super().__init__(
env_config_to_test, output_dir, env_type, env_sub_type, event_manager
)
self.env_config_to_test = env_config_to_test
def setup_environment(
self,
services_managers: list[IServiceManager],
test_config: TestConfig,
global_config: GlobalConfig,
timestamp: str,
plugin_loader: PluginLoader,
):
"""Set up the execution environment."""
self.services_managers = services_managers
self.test_config = test_config
self.plugin_loader = plugin_loader
self.global_config = global_config
self.logger.debug("Setting up execution environment...")
# Modify service commands or environment variables as needed
for service in self.services_managers:
if self.is_service_compatible(service):
# Add environment variables, wrappers, or modify commands
service.environments["YOUR_ENV_VAR"] = "value"
# Modify run commands if needed
service.run_cmd["pre_run_cmds"].append(
self.generate_command(service.service_name)
)
# Add post-processing commands if needed
service.run_cmd["post_run_cmds"].append(
f"process_output {service.service_name}"
)
def is_service_compatible(self, service: IServiceManager) -> bool:
"""Check if a service is compatible with this execution environment."""
# Check if the service has the required compatibility flag
return service.service_config_to_test.implementation.get("your_plugin_compatible", False)
def generate_command(self, service_name: str) -> str:
"""Generate a command for the given service."""
# Create environment-specific commands
return f"your_tool --service {service_name} --param {self.env_config_to_test.parameter1}"
4. Create the Plugin Documentation¤
Create a comprehensive README.md file following the PANTHER documentation template:
# Your Plugin Name
> **Plugin Type**: Environment (execution_environment)
> **Verified Source Location**: `plugins/environments/execution_environment/your_plugin_name/`
## Purpose and Overview
Describe your plugin's purpose and how it works.
## Requirements and Dependencies
List all dependencies required by this plugin.
## Configuration Options
Document all configuration parameters.
## Usage Examples
Provide examples of how to use your plugin.
## Extension Points
Document how your plugin can be extended.
## Testing and Verification
Explain how to test your plugin.
## Troubleshooting
Document common issues and solutions.
5. Register the Plugin¤
Make sure your plugin can be discovered by PANTHER by updating the __init__.py
file:
from panther.plugins.environments.execution_environment.your_plugin_name.your_plugin_name import YourPluginEnvironment
__all__ = ["YourPluginEnvironment"]
Testing Your Plugin¤
- Create a test configuration file:
tests:
- name: "Test with Your Execution Plugin"
execution_environment:
- name: "your_plugin_instance"
type: "execution_environment"
implementation: "your_plugin_name"
config:
parameter1: "value1"
parameter2: 200
services:
server:
name: "test_server"
implementation:
name: "test_implementation"
type: "iut"
your_plugin_compatible: true
- Run PANTHER with your test configuration:
python -m panther -c path/to/your/test/config.yaml
- Debug any issues and refine your implementation.
Best Practices¤
- Service Compatibility: Clearly define how services indicate compatibility with your environment
- Minimal Interference: Design your plugin to have minimal impact on service behavior unless explicitly desired
- Resource Management: Properly manage any resources your plugin allocates
- Output Collection: Provide clear mechanisms for collecting and analyzing plugin-generated data
- Documentation: Keep your README.md updated with accurate information
Example Implementation¤
For reference, you can examine existing execution environment plugins:
- GPerf CPU:
plugins/environments/execution_environment/gperf_cpu/
- GPerf Heap:
plugins/environments/execution_environment/gperf_heap/
- Strace:
plugins/environments/execution_environment/strace/