onConnection('provisioning'); $this->onQueue('provisioning'); } public function handle(): void { $host = Host::query()->where('uuid', $this->uuid)->first(); if ($host === null) { return; } foreach ($host->runs()->get() as $run) { // Block until the runner lock is free (a long step may hold it for up // to the step timeout), then delete — cascades events + resources. Cache::lock('run:'.$run->uuid, 2200)->block(2100, fn () => $run->delete()); } // The record identifier lives on the row about to be deleted, so this // has to happen first — otherwise the host's management address stays // published with nothing left to clean it up. if (filled($host->dns_record_id)) { try { app(HetznerDnsClient::class)->deleteRecord($host->dns_record_id); } catch (\Throwable $e) { Log::warning('could not delete host DNS record', [ 'host' => $host->uuid, 'record' => $host->dns_record_id, 'error' => $e->getMessage(), ]); } } if (filled($host->wg_pubkey)) { // Tombstone the console's view of this peer as well. The FK only // nulls host_id, which would leave an enabled-but-absent row behind: // shown forever as "wird angewendet", and re-enabling it would put a // deleted host's key back on the hub. Soft-deleting hands it to the // same machinery every other revocation uses — the removal below // clears the tombstone, and a sync retries if that removal is lost. VpnPeer::query()->where('public_key', $host->wg_pubkey)->delete(); RemoveWireguardPeer::dispatch($host->wg_pubkey); } $host->delete(); } }