65 lines
2.1 KiB
PHP
65 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Labs;
|
|
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* Parle au service correcteur (Go, sur l'hyperviseur) par son socket Unix.
|
|
* Le portail n'envoie que des identifiants : jamais une commande. Les
|
|
* commandes sont lues dans le lab.yaml par le correcteur lui-même.
|
|
*/
|
|
class ClientCorrecteur
|
|
{
|
|
/**
|
|
* @return array{reussi: bool, erreur: ?string}
|
|
*/
|
|
public function verifier(string $instanceId, string $lab, string $verification): array
|
|
{
|
|
// 10 s par vérification côté correcteur, plus une marge.
|
|
$reponse = $this->envoyer(['instance' => $instanceId, 'lab' => $lab, 'verification' => $verification], 15);
|
|
|
|
return ['reussi' => $reponse['reussi'], 'erreur' => $reponse['erreur'] ?? null];
|
|
}
|
|
|
|
/**
|
|
* Sonde de santé (self-healing) : état libvirt de la VM et réponse de son
|
|
* agent invité. Rien n'est exécuté dans la VM.
|
|
*
|
|
* @return array{repond: bool, etat: ?string, erreur: ?string}
|
|
*/
|
|
public function sante(string $instanceId): array
|
|
{
|
|
// 8 s maximum côté correcteur, plus une marge.
|
|
$reponse = $this->envoyer(['instance' => $instanceId, 'sante' => true], 10);
|
|
|
|
return ['repond' => $reponse['reussi'], 'etat' => $reponse['etat'] ?? null, 'erreur' => $reponse['erreur'] ?? null];
|
|
}
|
|
|
|
/**
|
|
* @param array<string, string|bool> $requete
|
|
* @return array{reussi: bool, erreur?: string, etat?: string}
|
|
*/
|
|
private function envoyer(array $requete, int $delai): array
|
|
{
|
|
$flux = @stream_socket_client('unix://'.config('labs.correcteur.socket'), $codeErreur, $messageErreur, 2);
|
|
|
|
if ($flux === false) {
|
|
throw new RuntimeException("Correcteur injoignable : {$messageErreur}");
|
|
}
|
|
|
|
stream_set_timeout($flux, $delai);
|
|
|
|
fwrite($flux, json_encode($requete)."\n");
|
|
$ligne = fgets($flux);
|
|
fclose($flux);
|
|
|
|
$reponse = is_string($ligne) ? json_decode($ligne, true) : null;
|
|
|
|
if (! is_array($reponse) || ! is_bool($reponse['reussi'] ?? null)) {
|
|
throw new RuntimeException('Réponse illisible du correcteur');
|
|
}
|
|
|
|
return $reponse;
|
|
}
|
|
}
|