domovoy/bin/run-scan-worker.php

93 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
/**
* CLI worker for running pending scan jobs.
*
* Usage:
* php bin/run-scan-worker.php # Run one pending job and exit
* php bin/run-scan-worker.php --loop # Infinite loop, process all pending jobs
*/
require dirname(__DIR__) . '/vendor/autoload.php';
$dotenv = \Dotenv\Dotenv::createImmutable(dirname(__DIR__));
$dotenv->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";
}
}
}