93 lines
2.9 KiB
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);
|
|
|
|
$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";
|
|
}
|
|
}
|
|
}
|