heat->listerStacks() as $stack) { if (str_starts_with($stack['nom'], "{$base}-e") && $stack['statut'] !== 'DELETE_IN_PROGRESS') { $this->heat->supprimerStack($stack['nom'], $stack['id']); } } } /** * @param (callable(string, string): void)|null $apresCreation appelé dès que Heat a accepté la stack (nom, id) * @return array{nom: string, id: string, instances: array} * * @throws RuntimeException si Heat refuse la stack ou si elle n'aboutit pas (elle est alors supprimée) */ public function fabriquer(DefinitionLab $lab, string $nom, ?callable $apresCreation = null): array { ['template' => $template] = $this->generateur->genererDepuis($lab, $nom); $stack = $this->heat->creerStack($nom, $template); if ($apresCreation !== null) { $apresCreation($nom, $stack['id']); } $etat = $this->attendre($nom, $stack['id']); if ($etat['statut'] !== 'CREATE_COMPLETE') { $this->heat->supprimerStack($nom, $stack['id']); throw new RuntimeException("La stack {$nom} n'a pas abouti : {$etat['statut']} ({$etat['raison']})"); } $instances = []; foreach ($lab->machines as $machine) { $instances[$machine['nom']] = $etat['sorties'][GenerateurTemplateHeat::cle($machine['nom']).'_id']; } return ['nom' => $nom, 'id' => $stack['id'], 'instances' => $instances]; } /** * @return array{statut: string, raison: ?string, sorties: array} */ private function attendre(string $nom, string $id): array { $limite = time() + self::ATTENTE_MAX_SECONDES; do { $etat = $this->heat->etatStack($nom, $id); if (! str_ends_with($etat['statut'], '_IN_PROGRESS')) { return $etat; } sleep(2); } while (time() < $limite); return ['statut' => 'DELAI_DEPASSE', 'raison' => 'plus de '.self::ATTENTE_MAX_SECONDES.' s', 'sorties' => []]; } }