feat: Implement YAML Configuration Management System

- Add comprehensive YAML configuration files for production and development
- Implement configuration validation with detailed error reporting
- Add configuration installation script with backup and directory creation
- Create configuration documentation with examples and best practices
- Add environment-specific configuration overrides
- Implement configuration validation script with path checking
- Support hot configuration reloading and environment variables
- Update TODO and CHANGELOG to reflect completion
This commit is contained in:
Joe Particle 2025-07-17 04:43:16 +00:00
parent 5c7a697ea4
commit 21cdf72b81
8 changed files with 1483 additions and 1 deletions

3
.gitignore vendored
View file

@ -92,3 +92,6 @@ __pycache__/
# Service file symlinks (tracked in git)
# These are symlinks to actual system files for tracking changes
!src/apt-ostree.py/systemd-symlinks/
src/rpm-ostree-main

View file

@ -198,7 +198,14 @@
- Log validation and statistics
- Enhanced systemd integration
- Full backward compatibility with existing configurations
- 🎯 **Configuration Management**: YAML-based configuration with validation
- ✅ **Configuration Management**: YAML-based configuration with validation
- Created comprehensive YAML configuration files for production and development
- Implemented configuration validation with detailed error reporting
- Added configuration installation script with backup and directory creation
- Created configuration documentation with examples and best practices
- Added environment-specific configuration overrides
- Implemented configuration validation script with path checking
- Configuration system supports hot reloading and environment variables
- 🎯 **Security Hardening**: Additional security policies and access controls
- 📋 **Project Relocation**: Move project from $HOME to /opt to eliminate ProtectHome=false requirement
- Relocate development environment from /home/joe/particle-os-tools to /opt/particle-os-tools

View file

@ -11,6 +11,14 @@
- Signal emission using correct dbus-next pattern (direct method calls, not .emit())
- Updated test scripts for apt-ostreed service name and correct method signatures
- Fixed dbus-next signal definitions and emission patterns
- **YAML Configuration Management System** - Complete configuration system implementation
- Comprehensive YAML configuration files for production and development environments
- Configuration validation with detailed error reporting and schema validation
- Configuration installation script with automatic backup and directory creation
- Environment-specific configuration overrides and environment variable support
- Configuration documentation with examples, best practices, and troubleshooting guide
- Configuration validation script with YAML syntax and path existence checking
- Hot configuration reloading support for runtime configuration changes
### Fixed
- Signal emission errors in D-Bus interface

View file

@ -0,0 +1,395 @@
# apt-ostree Daemon Configuration
This directory contains configuration files for the apt-ostree daemon. The daemon uses YAML-based configuration with comprehensive validation and environment-specific overrides.
## Configuration Files
### Main Configuration Files
- **`apt-ostreed.yaml`** - Production configuration with comprehensive settings
- **`apt-ostreed-dev.yaml`** - Development configuration optimized for testing and debugging
### Configuration Loading Order
The daemon loads configuration in the following order (later files override earlier ones):
1. Built-in defaults
2. `/etc/apt-ostree/config.yaml` (production)
3. `/etc/apt-ostree/config-{env}.yaml` (environment-specific)
4. Environment variables (prefixed with `APT_OSTREE_`)
## Configuration Sections
### Daemon Core Configuration
```yaml
daemon:
dbus:
bus_name: "org.debian.aptostree1"
object_path: "/org/debian/aptostree1"
concurrency:
max_workers: 3
transaction_timeout: 300 # seconds
logging:
level: "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL
format: "json" # json, text
file: "/var/log/apt-ostree/daemon.log"
max_size: "100MB"
max_files: 5
rotation_strategy: "size" # size, time, hybrid
# ... more logging options
auto_update_policy: "none" # none, check, download, install
```
### System Root Configuration
```yaml
sysroot:
path: "/"
repo_path: "/var/lib/ostree/repo"
```
### Security Configuration
```yaml
security:
polkit:
enabled: true
action_id: "org.debian.aptostree1.manage"
timeout: 300
authorization:
require_authorization: true
allowed_users: [] # Empty = root only
allowed_groups: [] # Empty = root only
dbus:
require_authentication: true
allowed_connections: []
```
### Performance Configuration
```yaml
performance:
memory:
max_heap_size: "512MB"
max_stack_size: "8MB"
cpu:
max_workers_per_cpu: 2
worker_timeout: 60
filesystem:
max_open_files: 1024
max_file_size: "100MB"
network:
connection_timeout: 30
read_timeout: 60
max_connections: 10
```
### Transaction Management
```yaml
transactions:
storage:
type: "memory" # memory, file, database
file_path: "/var/lib/apt-ostree/transactions"
max_transactions: 100
rollback:
enabled: true
max_rollback_depth: 5
auto_rollback_on_failure: true
progress:
enabled: true
update_interval: 1
detailed_progress: true
```
### Package Management
```yaml
packages:
apt:
cache_dir: "/var/cache/apt-ostree"
state_dir: "/var/lib/apt-ostree"
lists_dir: "/var/lib/apt/lists"
sources_list: "/etc/apt/sources.list"
preferences_file: "/etc/apt/preferences"
installation:
download_only: false
install_recommends: true
install_suggests: false
allow_downgrade: false
allow_remove_essential: false
verification:
verify_signatures: true
verify_checksums: true
allow_unauthenticated: false
```
### OSTree Integration
```yaml
ostree:
repo:
path: "/var/lib/ostree/repo"
mode: "archive" # archive, bare, bare-user
compression: true
deployment:
auto_deploy: false
deploy_timeout: 300
max_deployments: 10
layers:
enabled: true
layer_dir: "/var/lib/apt-ostree/layers"
max_layers: 50
layer_size_limit: "1GB"
```
### Monitoring and Health Checks
```yaml
monitoring:
health:
enabled: true
check_interval: 60
timeout: 30
metrics:
enabled: true
collection_interval: 300
retention_days: 7
alerts:
enabled: false
email_notifications: false
log_alerts: true
```
### Development and Testing
```yaml
development:
test_mode:
enabled: false
mock_ostree: false
mock_apt: false
debug:
enabled: false
verbose_logging: false
trace_transactions: false
paths:
source_dir: "/home/joe/particle-os-tools/src/apt-ostree.py"
test_data_dir: "/tmp/apt-ostree-test"
```
## Environment-Specific Configuration
The configuration system supports environment-specific overrides:
```yaml
environment:
env: "production" # development, testing, production
production:
logging:
level: "WARNING"
max_files: 10
security:
require_authorization: true
development:
logging:
level: "DEBUG"
max_files: 3
security:
require_authorization: false
development:
test_mode:
enabled: true
testing:
logging:
level: "INFO"
file: "/tmp/apt-ostree-test.log"
development:
test_mode:
enabled: true
mock_ostree: true
mock_apt: true
```
## Environment Variables
You can override configuration values using environment variables. The format is:
`APT_OSTREE_{SECTION}_{SUBSECTION}_{KEY}`
Examples:
- `APT_OSTREE_DAEMON_LOGGING_LEVEL=DEBUG`
- `APT_OSTREE_SECURITY_AUTHORIZATION_REQUIRE_AUTHORIZATION=false`
- `APT_OSTREE_PERFORMANCE_MEMORY_MAX_HEAP_SIZE=256MB`
## Configuration Validation
The configuration system includes comprehensive validation:
- **Type checking**: Ensures values are of the correct type
- **Range validation**: Validates numeric values within specified ranges
- **Pattern matching**: Validates strings against regex patterns
- **Required fields**: Ensures required configuration sections are present
- **Enumeration values**: Validates against allowed values
### Validation Errors
If configuration validation fails, the daemon will:
1. Log detailed error messages
2. Show which configuration values are invalid
3. Provide suggestions for fixing the issues
4. Exit with an error code
## Configuration Reloading
The daemon supports hot configuration reloading:
```bash
# Reload configuration without restarting the daemon
systemctl reload apt-ostreed.service
```
**Note**: Not all configuration changes can be applied without a restart. The daemon will log which changes require a restart.
## Configuration Examples
### Minimal Configuration
```yaml
daemon:
dbus:
bus_name: "org.debian.aptostree1"
object_path: "/org/debian/aptostree1"
logging:
level: "INFO"
file: "/var/log/apt-ostree/daemon.log"
sysroot:
path: "/"
repo_path: "/var/lib/ostree/repo"
```
### Development Configuration
```yaml
environment:
env: "development"
daemon:
logging:
level: "DEBUG"
format: "text"
file: "/tmp/apt-ostree-dev.log"
development:
test_mode:
enabled: true
mock_ostree: true
mock_apt: true
```
### Production Configuration
```yaml
environment:
env: "production"
daemon:
logging:
level: "WARNING"
max_files: 10
security:
authorization:
require_authorization: true
performance:
memory:
max_heap_size: "1GB"
```
## Troubleshooting
### Common Configuration Issues
1. **Permission Denied**: Ensure the daemon has read access to configuration files
2. **Invalid YAML**: Check for YAML syntax errors (indentation, quotes, etc.)
3. **Missing Required Fields**: Ensure all required configuration sections are present
4. **Invalid Values**: Check that values match the expected format and ranges
### Configuration Validation
To validate your configuration:
```bash
# Test configuration loading
python3 -c "
from utils.config import ConfigManager
config = ConfigManager('/path/to/config.yaml')
if config.validate():
print('Configuration is valid')
else:
print('Configuration errors:')
print(config.format_validation_report())
"
```
### Configuration Debugging
Enable debug logging to see configuration loading details:
```yaml
daemon:
logging:
level: "DEBUG"
```
## Best Practices
1. **Use Environment-Specific Configs**: Create separate configs for development, testing, and production
2. **Validate Early**: Test configuration changes before deploying
3. **Document Changes**: Keep track of configuration changes and their impact
4. **Use Environment Variables**: Override sensitive values with environment variables
5. **Backup Configurations**: Keep backups of working configurations
6. **Test Reloads**: Verify that configuration reloads work as expected
## Migration from Legacy Configuration
If you're migrating from a legacy configuration system:
1. Export your current settings
2. Map them to the new YAML format
3. Validate the new configuration
4. Test with the new daemon
5. Update deployment scripts
## Support
For configuration-related issues:
1. Check the validation error messages
2. Review the configuration schema documentation
3. Test with minimal configuration
4. Enable debug logging for detailed information

View file

@ -0,0 +1,218 @@
# apt-ostree daemon development configuration
# This file contains development-specific settings for testing and debugging
# Environment override
environment:
env: "development"
# Daemon core configuration (development overrides)
daemon:
# D-Bus configuration
dbus:
bus_name: "org.debian.aptostree1"
object_path: "/org/debian/aptostree1"
# Concurrency and performance settings (reduced for development)
concurrency:
max_workers: 2
transaction_timeout: 120 # shorter timeout for faster testing
# Logging configuration (verbose for development)
logging:
level: "DEBUG" # More verbose logging
format: "text" # Human-readable format
file: "/tmp/apt-ostree-dev.log" # Local development log
max_size: "10MB" # Smaller files for development
max_files: 3
rotation_strategy: "size"
rotation_interval: 1
rotation_unit: "D"
compression: false # Disable compression for faster access
correlation_id: true
performance_monitoring: true
cleanup_old_logs: true
cleanup_days: 7 # Keep logs for shorter period
include_hostname: true
include_version: true
# Automatic update policy
auto_update_policy: "none"
# System root configuration (development paths)
sysroot:
path: "/"
repo_path: "/tmp/apt-ostree-dev/repo" # Local development repo
# Shell integration settings (development-friendly)
shell_integration:
enabled: true
command_timeout: 15 # Shorter timeout for faster testing
max_output_size: "100KB" # Smaller output for development
enable_sudo: false # Disable sudo for development
sudo_timeout: 60
# Security configuration (relaxed for development)
security:
# PolicyKit integration
polkit:
enabled: false # Disable for development
action_id: "org.debian.aptostree1.manage"
timeout: 60
# Client authorization (relaxed)
authorization:
require_authorization: false # Disable for development
allowed_users: []
allowed_groups: []
# D-Bus security (relaxed)
dbus:
require_authentication: false # Disable for development
allowed_connections: []
# Performance and resource limits (reduced for development)
performance:
# Memory limits (reduced)
memory:
max_heap_size: "128MB"
max_stack_size: "4MB"
# CPU limits (reduced)
cpu:
max_workers_per_cpu: 1
worker_timeout: 30
# File system limits (reduced)
filesystem:
max_open_files: 256
max_file_size: "10MB"
# Network limits (reduced)
network:
connection_timeout: 15
read_timeout: 30
max_connections: 5
# Transaction management (development settings)
transactions:
# Transaction storage (file-based for development)
storage:
type: "file" # Use file storage for persistence
file_path: "/tmp/apt-ostree-dev/transactions"
max_transactions: 20 # Fewer transactions for development
# Rollback settings
rollback:
enabled: true
max_rollback_depth: 3 # Fewer rollbacks for development
auto_rollback_on_failure: true
# Progress reporting (more frequent for development)
progress:
enabled: true
update_interval: 0.5 # More frequent updates
detailed_progress: true
# Package management (development settings)
packages:
# APT configuration (development paths)
apt:
cache_dir: "/tmp/apt-ostree-dev/cache"
state_dir: "/tmp/apt-ostree-dev/state"
lists_dir: "/tmp/apt-ostree-dev/lists"
sources_list: "/tmp/apt-ostree-dev/sources.list"
preferences_file: "/tmp/apt-ostree-dev/preferences"
# Package installation (development-friendly)
installation:
download_only: true # Download only for development
install_recommends: false # Skip recommends for faster testing
install_suggests: false
allow_downgrade: true # Allow downgrades for testing
allow_remove_essential: false
# Package verification (relaxed for development)
verification:
verify_signatures: false # Disable for development
verify_checksums: true
allow_unauthenticated: true # Allow unauthenticated for development
# OSTree integration (development settings)
ostree:
# Repository settings (development paths)
repo:
path: "/tmp/apt-ostree-dev/repo"
mode: "bare-user" # Use bare-user mode for development
compression: false # Disable compression for faster access
# Deployment settings (development-friendly)
deployment:
auto_deploy: false
deploy_timeout: 60 # Shorter timeout
max_deployments: 5 # Fewer deployments
# Layer management (development settings)
layers:
enabled: true
layer_dir: "/tmp/apt-ostree-dev/layers"
max_layers: 10 # Fewer layers for development
layer_size_limit: "100MB" # Smaller size limit
# Monitoring and health checks (development settings)
monitoring:
# Health check settings (more frequent for development)
health:
enabled: true
check_interval: 30 # More frequent checks
timeout: 15 # Shorter timeout
# Metrics collection (reduced for development)
metrics:
enabled: false # Disable metrics for development
collection_interval: 300
retention_days: 1
# Alerting (development settings)
alerts:
enabled: false
email_notifications: false
log_alerts: true
# Development and testing (enabled)
development:
# Test mode settings (enabled for development)
test_mode:
enabled: true # Enable test mode
mock_ostree: true # Use mock OSTree
mock_apt: true # Use mock APT
# Debug settings (enabled for development)
debug:
enabled: true # Enable debug mode
verbose_logging: true # Enable verbose logging
trace_transactions: true # Enable transaction tracing
# Development paths
paths:
source_dir: "/home/joe/particle-os-tools/src/apt-ostree.py"
test_data_dir: "/tmp/apt-ostree-test"
# Development-specific overrides
development_overrides:
# Fast mode for rapid testing
fast_mode:
enabled: true
skip_validation: true
skip_cleanup: true
# Mock services for testing
mock_services:
ostree: true
apt: true
polkit: true
# Development tools
tools:
enable_repl: true # Enable REPL for debugging
enable_profiling: false # Disable profiling by default
enable_coverage: false # Disable coverage by default

View file

@ -0,0 +1,228 @@
# apt-ostree daemon configuration file
# This file configures the apt-ostree daemon behavior and settings
# Daemon core configuration
daemon:
# D-Bus configuration
dbus:
bus_name: "org.debian.aptostree1"
object_path: "/org/debian/aptostree1"
# Concurrency and performance settings
concurrency:
max_workers: 3
transaction_timeout: 300 # seconds
# Logging configuration
logging:
level: "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL
format: "json" # json, text
file: "/var/log/apt-ostree/daemon.log"
max_size: "100MB" # e.g., 100MB, 1GB
max_files: 5
rotation_strategy: "size" # size, time, hybrid
rotation_interval: 1
rotation_unit: "D" # D=days, H=hours, M=minutes
compression: true
correlation_id: true
performance_monitoring: true
cleanup_old_logs: true
cleanup_days: 30
include_hostname: true
include_version: true
# Automatic update policy
auto_update_policy: "none" # none, check, download, install
# System root configuration
sysroot:
path: "/"
repo_path: "/var/lib/ostree/repo"
# Shell integration settings
shell_integration:
enabled: true
command_timeout: 30 # seconds
max_output_size: "1MB"
enable_sudo: true
sudo_timeout: 300 # seconds
# Security configuration
security:
# PolicyKit integration
polkit:
enabled: true
action_id: "org.debian.aptostree1.manage"
timeout: 300 # seconds
# Client authorization
authorization:
require_authorization: true
allowed_users: [] # Empty list means root only
allowed_groups: [] # Empty list means root only
# D-Bus security
dbus:
require_authentication: true
allowed_connections: [] # Empty list means system bus only
# Performance and resource limits
performance:
# Memory limits
memory:
max_heap_size: "512MB"
max_stack_size: "8MB"
# CPU limits
cpu:
max_workers_per_cpu: 2
worker_timeout: 60 # seconds
# File system limits
filesystem:
max_open_files: 1024
max_file_size: "100MB"
# Network limits
network:
connection_timeout: 30 # seconds
read_timeout: 60 # seconds
max_connections: 10
# Transaction management
transactions:
# Transaction storage
storage:
type: "memory" # memory, file, database
file_path: "/var/lib/apt-ostree/transactions"
max_transactions: 100
# Rollback settings
rollback:
enabled: true
max_rollback_depth: 5
auto_rollback_on_failure: true
# Progress reporting
progress:
enabled: true
update_interval: 1 # seconds
detailed_progress: true
# Package management
packages:
# APT configuration
apt:
cache_dir: "/var/cache/apt-ostree"
state_dir: "/var/lib/apt-ostree"
lists_dir: "/var/lib/apt/lists"
sources_list: "/etc/apt/sources.list"
preferences_file: "/etc/apt/preferences"
# Package installation
installation:
download_only: false
install_recommends: true
install_suggests: false
allow_downgrade: false
allow_remove_essential: false
# Package verification
verification:
verify_signatures: true
verify_checksums: true
allow_unauthenticated: false
# OSTree integration
ostree:
# Repository settings
repo:
path: "/var/lib/ostree/repo"
mode: "archive" # archive, bare, bare-user
compression: true
# Deployment settings
deployment:
auto_deploy: false
deploy_timeout: 300 # seconds
max_deployments: 10
# Layer management
layers:
enabled: true
layer_dir: "/var/lib/apt-ostree/layers"
max_layers: 50
layer_size_limit: "1GB"
# Monitoring and health checks
monitoring:
# Health check settings
health:
enabled: true
check_interval: 60 # seconds
timeout: 30 # seconds
# Metrics collection
metrics:
enabled: true
collection_interval: 300 # seconds
retention_days: 7
# Alerting
alerts:
enabled: false
email_notifications: false
log_alerts: true
# Development and testing
development:
# Test mode settings
test_mode:
enabled: false
mock_ostree: false
mock_apt: false
# Debug settings
debug:
enabled: false
verbose_logging: false
trace_transactions: false
# Development paths
paths:
source_dir: "/home/joe/particle-os-tools/src/apt-ostree.py"
test_data_dir: "/tmp/apt-ostree-test"
# Environment-specific overrides
# These can be overridden by environment variables
environment:
# Environment detection
env: "production" # development, testing, production
# Environment-specific settings
production:
logging:
level: "WARNING"
max_files: 10
security:
require_authorization: true
development:
logging:
level: "DEBUG"
max_files: 3
security:
require_authorization: false
development:
test_mode:
enabled: true
testing:
logging:
level: "INFO"
file: "/tmp/apt-ostree-test.log"
development:
test_mode:
enabled: true
mock_ostree: true
mock_apt: true

View file

@ -0,0 +1,362 @@
#!/bin/bash
# Install apt-ostree daemon configuration files
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
CONFIG_DIR="/etc/apt-ostree"
BACKUP_DIR="/etc/apt-ostree/backup"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to check if running as root
check_root() {
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root"
exit 1
fi
}
# Function to create backup
create_backup() {
local file="$1"
local backup_file="$BACKUP_DIR/$(basename "$file").$(date +%Y%m%d_%H%M%S)"
if [[ -f "$file" ]]; then
print_status "Creating backup of existing configuration: $backup_file"
mkdir -p "$BACKUP_DIR"
cp "$file" "$backup_file"
print_success "Backup created: $backup_file"
fi
}
# Function to install configuration file
install_config() {
local source_file="$1"
local dest_file="$2"
local description="$3"
if [[ ! -f "$source_file" ]]; then
print_error "Source configuration file not found: $source_file"
return 1
fi
print_status "Installing $description..."
# Create backup if destination exists
create_backup "$dest_file"
# Install the configuration file
cp "$source_file" "$dest_file"
chmod 644 "$dest_file"
print_success "$description installed: $dest_file"
}
# Function to validate configuration
validate_config() {
local config_file="$1"
local description="$2"
print_status "Validating $description..."
if [[ -f "$config_file" ]]; then
if python3 "$SCRIPT_DIR/validate_config.py" "$config_file" >/dev/null 2>&1; then
print_success "$description validation passed"
else
print_error "$description validation failed"
return 1
fi
else
print_warning "$description not found, skipping validation"
fi
}
# Function to create development directories
create_dev_dirs() {
print_status "Creating development directories..."
local dev_dirs=(
"/tmp/apt-ostree-dev"
"/tmp/apt-ostree-dev/repo"
"/tmp/apt-ostree-dev/transactions"
"/tmp/apt-ostree-dev/cache"
"/tmp/apt-ostree-dev/state"
"/tmp/apt-ostree-dev/lists"
"/tmp/apt-ostree-dev/layers"
"/tmp/apt-ostree-test"
)
for dir in "${dev_dirs[@]}"; do
if [[ ! -d "$dir" ]]; then
mkdir -p "$dir"
print_success "Created directory: $dir"
else
print_status "Directory already exists: $dir"
fi
done
}
# Function to create production directories
create_prod_dirs() {
print_status "Creating production directories..."
local prod_dirs=(
"/var/log/apt-ostree"
"/var/lib/apt-ostree"
"/var/lib/apt-ostree/transactions"
"/var/lib/apt-ostree/layers"
"/var/cache/apt-ostree"
)
for dir in "${prod_dirs[@]}"; do
if [[ ! -d "$dir" ]]; then
mkdir -p "$dir"
chown root:root "$dir"
chmod 755 "$dir"
print_success "Created directory: $dir"
else
print_status "Directory already exists: $dir"
fi
done
}
# Function to show usage
show_usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -d, --dev Install development configuration"
echo " -p, --prod Install production configuration"
echo " -a, --all Install both configurations"
echo " --create-dirs Create necessary directories"
echo " --validate-only Only validate existing configurations"
echo " --backup-only Only create backups of existing configurations"
echo ""
echo "Examples:"
echo " $0 --dev Install development configuration"
echo " $0 --prod --create-dirs Install production config and create directories"
echo " $0 --all Install both configurations"
echo " $0 --validate-only Validate existing configurations"
}
# Function to install development configuration
install_dev_config() {
print_status "Installing development configuration..."
# Create development directories
create_dev_dirs
# Install development configuration
install_config \
"$SCRIPT_DIR/apt-ostreed-dev.yaml" \
"$CONFIG_DIR/config-dev.yaml" \
"development configuration"
# Create symlink for development
if [[ -L "$CONFIG_DIR/config.yaml" ]]; then
rm "$CONFIG_DIR/config.yaml"
fi
ln -sf "$CONFIG_DIR/config-dev.yaml" "$CONFIG_DIR/config.yaml"
print_success "Development configuration activated"
}
# Function to install production configuration
install_prod_config() {
print_status "Installing production configuration..."
# Create production directories
create_prod_dirs
# Install production configuration
install_config \
"$SCRIPT_DIR/apt-ostreed.yaml" \
"$CONFIG_DIR/config-prod.yaml" \
"production configuration"
# Create symlink for production
if [[ -L "$CONFIG_DIR/config.yaml" ]]; then
rm "$CONFIG_DIR/config.yaml"
fi
ln -sf "$CONFIG_DIR/config-prod.yaml" "$CONFIG_DIR/config.yaml"
print_success "Production configuration activated"
}
# Function to validate all configurations
validate_all_configs() {
print_status "Validating all configurations..."
local configs=(
"$CONFIG_DIR/config.yaml"
"$CONFIG_DIR/config-dev.yaml"
"$CONFIG_DIR/config-prod.yaml"
)
local all_valid=true
for config in "${configs[@]}"; do
if [[ -f "$config" ]]; then
if ! validate_config "$config" "$(basename "$config")"; then
all_valid=false
fi
fi
done
if [[ "$all_valid" == "true" ]]; then
print_success "All configurations are valid"
else
print_error "Some configurations have validation errors"
exit 1
fi
}
# Function to create backups only
create_backups_only() {
print_status "Creating backups of existing configurations..."
local configs=(
"$CONFIG_DIR/config.yaml"
"$CONFIG_DIR/config-dev.yaml"
"$CONFIG_DIR/config-prod.yaml"
)
for config in "${configs[@]}"; do
if [[ -f "$config" ]]; then
create_backup "$config"
fi
done
print_success "Backup process completed"
}
# Main function
main() {
local install_dev=false
local install_prod=false
local create_dirs=false
local validate_only=false
local backup_only=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-d|--dev)
install_dev=true
shift
;;
-p|--prod)
install_prod=true
shift
;;
-a|--all)
install_dev=true
install_prod=true
shift
;;
--create-dirs)
create_dirs=true
shift
;;
--validate-only)
validate_only=true
shift
;;
--backup-only)
backup_only=true
shift
;;
*)
print_error "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Check if running as root
check_root
# Create configuration directory
if [[ ! -d "$CONFIG_DIR" ]]; then
print_status "Creating configuration directory: $CONFIG_DIR"
mkdir -p "$CONFIG_DIR"
chmod 755 "$CONFIG_DIR"
fi
# Handle different modes
if [[ "$backup_only" == "true" ]]; then
create_backups_only
exit 0
fi
if [[ "$validate_only" == "true" ]]; then
validate_all_configs
exit 0
fi
if [[ "$create_dirs" == "true" ]]; then
create_dev_dirs
create_prod_dirs
exit 0
fi
# Install configurations
if [[ "$install_dev" == "true" ]]; then
install_dev_config
fi
if [[ "$install_prod" == "true" ]]; then
install_prod_config
fi
# If no specific configuration was requested, install production by default
if [[ "$install_dev" == "false" && "$install_prod" == "false" ]]; then
print_status "No configuration specified, installing production configuration by default"
install_prod_config
fi
# Validate configurations
validate_all_configs
print_success "Configuration installation completed successfully"
echo ""
print_status "Configuration files installed in: $CONFIG_DIR"
print_status "Active configuration: $CONFIG_DIR/config.yaml"
print_status "Backup directory: $BACKUP_DIR"
echo ""
print_status "To switch configurations:"
echo " Development: ln -sf $CONFIG_DIR/config-dev.yaml $CONFIG_DIR/config.yaml"
echo " Production: ln -sf $CONFIG_DIR/config-prod.yaml $CONFIG_DIR/config.yaml"
}
# Run main function with all arguments
main "$@"

View file

@ -0,0 +1,261 @@
#!/usr/bin/env python3
"""
Configuration validation script for apt-ostree daemon
"""
import sys
import os
import argparse
import yaml
from pathlib import Path
# Add the python directory to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'python'))
from utils.config import ConfigManager, ConfigValidator
def validate_config_file(config_path: str, verbose: bool = False) -> bool:
"""Validate a configuration file"""
print(f"Validating configuration file: {config_path}")
if not os.path.exists(config_path):
print(f"❌ Configuration file not found: {config_path}")
return False
try:
# Load and validate configuration
config_manager = ConfigManager(config_path)
config = config_manager.load_config()
if not config:
print("❌ Failed to load configuration")
return False
# Validate the configuration
if not config_manager.validate():
print("❌ Configuration validation failed")
print("\nValidation errors:")
print(config_manager.format_validation_report())
return False
print("✅ Configuration is valid")
if verbose:
print("\nConfiguration summary:")
print_config_summary(config)
return True
except Exception as e:
print(f"❌ Error validating configuration: {e}")
return False
def print_config_summary(config: dict, indent: str = ""):
"""Print a summary of the configuration"""
for key, value in config.items():
if isinstance(value, dict):
print(f"{indent}{key}:")
print_config_summary(value, indent + " ")
else:
print(f"{indent}{key}: {value}")
def validate_yaml_syntax(config_path: str) -> bool:
"""Validate YAML syntax without loading into ConfigManager"""
print(f"Validating YAML syntax: {config_path}")
try:
with open(config_path, 'r') as f:
yaml.safe_load(f)
print("✅ YAML syntax is valid")
return True
except yaml.YAMLError as e:
print(f"❌ YAML syntax error: {e}")
return False
except Exception as e:
print(f"❌ Error reading file: {e}")
return False
def check_config_paths(config_path: str) -> bool:
"""Check if paths referenced in configuration exist"""
print(f"Checking configuration paths: {config_path}")
try:
with open(config_path, 'r') as f:
config = yaml.safe_load(f)
paths_to_check = []
# Extract paths from configuration
if 'daemon' in config and 'logging' in config['daemon']:
log_file = config['daemon']['logging'].get('file')
if log_file:
paths_to_check.append(('Log file directory', os.path.dirname(log_file)))
if 'sysroot' in config:
sysroot_path = config['sysroot'].get('path')
if sysroot_path:
paths_to_check.append(('System root', sysroot_path))
repo_path = config['sysroot'].get('repo_path')
if repo_path:
paths_to_check.append(('OSTree repository', repo_path))
if 'transactions' in config and 'storage' in config['transactions']:
storage_path = config['transactions']['storage'].get('file_path')
if storage_path:
paths_to_check.append(('Transaction storage', storage_path))
if 'packages' in config and 'apt' in config['packages']:
apt_paths = config['packages']['apt']
for key, path in apt_paths.items():
if isinstance(path, str) and os.path.isabs(path):
paths_to_check.append((f'APT {key}', path))
# Check each path
all_valid = True
for description, path in paths_to_check:
if os.path.exists(path):
print(f"{description}: {path}")
else:
print(f"⚠️ {description}: {path} (does not exist)")
all_valid = False
return all_valid
except Exception as e:
print(f"❌ Error checking paths: {e}")
return False
def generate_config_template(output_path: str):
"""Generate a minimal configuration template"""
template = {
'daemon': {
'dbus': {
'bus_name': 'org.debian.aptostree1',
'object_path': '/org/debian/aptostree1'
},
'concurrency': {
'max_workers': 3,
'transaction_timeout': 300
},
'logging': {
'level': 'INFO',
'format': 'json',
'file': '/var/log/apt-ostree/daemon.log',
'max_size': '100MB',
'max_files': 5,
'rotation_strategy': 'size',
'rotation_interval': 1,
'rotation_unit': 'D',
'compression': True,
'correlation_id': True,
'performance_monitoring': True,
'cleanup_old_logs': True,
'cleanup_days': 30,
'include_hostname': True,
'include_version': True
},
'auto_update_policy': 'none'
},
'sysroot': {
'path': '/',
'repo_path': '/var/lib/ostree/repo'
},
'security': {
'polkit': {
'enabled': True,
'action_id': 'org.debian.aptostree1.manage',
'timeout': 300
},
'authorization': {
'require_authorization': True,
'allowed_users': [],
'allowed_groups': []
},
'dbus': {
'require_authentication': True,
'allowed_connections': []
}
},
'development': {
'test_mode': {
'enabled': False,
'mock_ostree': False,
'mock_apt': False
},
'debug': {
'enabled': False,
'verbose_logging': False,
'trace_transactions': False
}
}
}
try:
with open(output_path, 'w') as f:
yaml.dump(template, f, default_flow_style=False, indent=2)
print(f"✅ Generated configuration template: {output_path}")
return True
except Exception as e:
print(f"❌ Error generating template: {e}")
return False
def main():
parser = argparse.ArgumentParser(description='Validate apt-ostree daemon configuration')
parser.add_argument('config_file', nargs='?', help='Configuration file to validate')
parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
parser.add_argument('--yaml-only', action='store_true', help='Only validate YAML syntax')
parser.add_argument('--check-paths', action='store_true', help='Check if referenced paths exist')
parser.add_argument('--generate-template', metavar='OUTPUT_PATH', help='Generate a minimal configuration template')
args = parser.parse_args()
if args.generate_template:
success = generate_config_template(args.generate_template)
sys.exit(0 if success else 1)
if not args.config_file:
# Default to checking all config files in the current directory
config_dir = Path(__file__).parent
config_files = list(config_dir.glob('*.yaml'))
if not config_files:
print("No configuration files found in current directory")
sys.exit(1)
print(f"Found {len(config_files)} configuration file(s)")
all_valid = True
for config_file in config_files:
print(f"\n{'='*50}")
success = validate_config_file(str(config_file), args.verbose)
if not success:
all_valid = False
if args.check_paths:
print()
check_config_paths(str(config_file))
sys.exit(0 if all_valid else 1)
# Validate single configuration file
if args.yaml_only:
success = validate_yaml_syntax(args.config_file)
else:
success = validate_config_file(args.config_file, args.verbose)
if success and args.check_paths:
print()
check_config_paths(args.config_file)
sys.exit(0 if success else 1)
if __name__ == '__main__':
main()