56 lines
1.9 KiB
PHP
56 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace App\Actions;
|
|
|
|
use App\Models\Host;
|
|
use App\Models\ProvisioningRun;
|
|
use App\Provisioning\Jobs\AdvanceRunJob;
|
|
use App\Support\HostName;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
/**
|
|
* Registers a fresh host and kicks off its onboarding run. The one-time root
|
|
* password lives encrypted in the run context and is scrubbed after SSH trust
|
|
* is established.
|
|
*/
|
|
class StartHostOnboarding
|
|
{
|
|
/**
|
|
* @param array{datacenter: string, public_ip: string, root_password: string} $input
|
|
*/
|
|
public function run(array $input): Host
|
|
{
|
|
// Host + run are created atomically; a partial insert would otherwise
|
|
// leave a permanently pending host with no run.
|
|
[$host, $run] = DB::transaction(function () use ($input) {
|
|
$host = Host::create([
|
|
// Den Namen vergibt CluPilot, nicht der Betreiber. Innerhalb
|
|
// DIESER Transaktion, weil HostName::claim die
|
|
// Rechenzentrums-Zeile sperrt und die Sperre nur bis zu deren
|
|
// Ende hält — außerhalb bekämen zwei gleichzeitige
|
|
// Anlegen-Vorgänge dieselbe Nummer.
|
|
'name' => HostName::claim($input['datacenter']),
|
|
'datacenter' => $input['datacenter'],
|
|
'public_ip' => $input['public_ip'],
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
$run = ProvisioningRun::create([
|
|
'subject_type' => Host::class,
|
|
'subject_id' => $host->id,
|
|
'pipeline' => 'host',
|
|
'status' => ProvisioningRun::STATUS_PENDING,
|
|
'current_step' => 0,
|
|
'context' => ['root_password' => Crypt::encryptString($input['root_password'])],
|
|
]);
|
|
|
|
return [$host, $run];
|
|
});
|
|
|
|
AdvanceRunJob::dispatch($run->uuid); // after commit — the run definitely exists
|
|
|
|
return $host;
|
|
}
|
|
}
|