Can you explain what the following script does?
#!/usr/bin/env python3
import os
import signal
import subprocess
import sys
import logging
import time
# Set up logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Global variable to store the daemon process
daemon_process = None
def create_config():
"""Process environment variables and create configuration."""
try:
config_vars = {
'FOO': os.getenv('FOO', '/config'),
'BAR': os.getenv('BAR', '/app')
}
# Validate required environment variables
for var, value in config_vars.items():
if not value:
raise ValueError(f"Required environment variable {var} is not set")
# Check if directories exist
if not os.path.exists(value):
logger.warning(f"Directory {value} for {var} does not exist. Creating it...")
os.makedirs(value, exist_ok=True)
logger.info("Configuration processed successfully")
return config_vars
except Exception as e:
logger.error(f"Error processing configuration: {str(e)}")
sys.exit(1)
def start_daemon():
"""Start the daemon process."""
global daemon_process
try:
# Start the daemon in the foreground
daemon_process = subprocess.Popen(
['flibd'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True
)
logger.info(f"Daemon started with PID {daemon_process.pid}")
# Start background thread to log daemon output
def log_output():
for line in daemon_process.stdout:
logger.info(f"Daemon output: {line.strip()}")
for line in daemon_process.stderr:
logger.error(f"Daemon error: {line.strip()}")
from threading import Thread
Thread(target=log_output, daemon=True).start()
except Exception as e:
logger.error(f"Failed to start daemon: {str(e)}")
sys.exit(1)
def stop_daemon():
"""Stop the daemon process."""
global daemon_process
if daemon_process:
try:
daemon_process.terminate()
daemon_process.wait(timeout=10) # Wait up to 10 seconds for graceful shutdown
logger.info("Daemon stopped successfully")
except subprocess.TimeoutExpired:
logger.warning("Daemon did not stop gracefully, forcing shutdown")
daemon_process.kill()
except Exception as e:
logger.error(f"Error stopping daemon: {str(e)}")
def handle_sighup(signum, frame):
"""Handle SIGHUP signal by restarting the daemon."""
logger.info("Received SIGHUP signal")
try:
stop_daemon()
start_daemon()
logger.info("Daemon restarted successfully")
except Exception as e:
logger.error(f"Failed to restart daemon: {str(e)}")
sys.exit(1)
def main():
"""Main function to run the wrapper."""
try:
# Process configuration
config = create_config()
# Set up signal handler
signal.signal(signal.SIGHUP, handle_sighup)
# Start daemon
start_daemon()
# Keep the script running and monitor the daemon
while True:
if daemon_process.poll() is not None:
exit_code = daemon_process.returncode
logger.error(f"Daemon process exited unexpectedly with code {exit_code}")
sys.exit(exit_code)
time.sleep(1)
except KeyboardInterrupt:
logger.info("Received shutdown signal")