$this->auth->jeton(), 'OpenStack-API-Version' => 'compute 2.99', ]) ->post(config('openstack.nova_url')."/servers/{$instanceId}/remote-consoles", [ 'remote_console' => ['protocol' => 'serial', 'type' => 'serial'], ]); if ($reponse->failed()) { throw new RuntimeException("Nova a refusé la demande de console série pour {$instanceId} : ".$reponse->body()); } return $reponse->json('remote_console.url'); } /** * Redémarrage forcé (bloc A, self-healing) : équivalent d'un appui sur * le bouton reset. Le disque de la VM est conservé. */ public function redemarrerForce(string $instanceId): void { $this->action($instanceId, ['reboot' => ['type' => 'HARD']]); } /** Démarre une VM éteinte (l'élève a lancé « poweroff »). */ public function demarrer(string $instanceId): void { $this->action($instanceId, ['os-start' => null]); } /** * @param array $corps */ private function action(string $instanceId, array $corps): void { $reponse = Http::withHeaders([ 'X-Auth-Token' => $this->auth->jeton(), 'OpenStack-API-Version' => 'compute 2.99', ]) ->post(config('openstack.nova_url')."/servers/{$instanceId}/action", $corps); if ($reponse->failed()) { throw new RuntimeException("Nova a refusé l'action ".array_key_first($corps)." sur {$instanceId} : ".$reponse->body()); } } }