safeLoad(); $pdo = new PDO( sprintf( 'mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4', getenv('DB_HOST') ?: 'db', (int)(getenv('DB_PORT') ?: 3306), getenv('DB_DATABASE') ?: 'domovoy' ), getenv('DB_USERNAME') ?: 'domovoy', getenv('DB_PASSWORD') ?: 'domovoy', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ] ); // Build dependencies manually (no DI container in CLI) $logger = new \Monolog\Logger('domovoy'); $logger->pushHandler(new \Monolog\Handler\StreamHandler(dirname(__DIR__) . '/storage/logs/scan-worker.log', \Monolog\Level::Debug)); $networkRangeRepository = new \Domovoy\Repositories\NetworkRangeRepository($pdo); $scanJobRepository = new \Domovoy\Repositories\ScanJobRepository($pdo); $discoveredHostRepository = new \Domovoy\Repositories\DiscoveredHostRepository($pdo); $pingScanner = new \Domovoy\Services\Discovery\PingScanner(); $tcpPortScanner = new \Domovoy\Services\Discovery\TcpPortScanner(); $arpTableReader = new \Domovoy\Services\Discovery\ArpTableReader(); $fingerprintService = new \Domovoy\Services\Discovery\HostFingerprintService(); $networkScanner = new \Domovoy\Services\Discovery\NetworkScanner( $pingScanner, $tcpPortScanner, $arpTableReader, $fingerprintService, $discoveredHostRepository ); $runner = new \Domovoy\Services\Jobs\ScanJobRunner($scanJobRepository, $networkScanner, $networkRangeRepository); $loopMode = in_array('--loop', $argv, true); if ($loopMode) { echo "Scan worker running in loop mode. Press Ctrl+C to stop.\n"; $logger->info('Scan worker started in loop mode'); // Handle SIGTERM for graceful shutdown if (function_exists('pcntl_signal')) { pcntl_signal(SIGTERM, function () use ($logger) { $logger->info('Received SIGTERM, shutting down gracefully'); exit(0); }); } while (true) { $job = $runner->runNext(); if ($job === null) { sleep(5); continue; } $logger->info('Scan job completed', ['job_id' => $job->id, 'status' => $job->status]); if (function_exists('pcntl_signal_dispatch')) { pcntl_signal_dispatch(); } } } else { $job = $runner->runNext(); if ($job === null) { echo "No pending scan jobs found.\n"; } else { echo "Scan job #{$job->id} completed: {$job->status}\n"; if ($job->errorMessage !== null) { echo "Error: {$job->errorMessage}\n"; } } }