CluPilotCloud/app/Models/ProvisioningRun.php

100 lines
3.0 KiB
PHP

<?php
namespace App\Models;
use App\Models\Concerns\HasUuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class ProvisioningRun extends Model
{
/** @use HasFactory<\Database\Factories\ProvisioningRunFactory> */
use HasFactory, HasUuid;
public const STATUS_PENDING = 'pending';
public const STATUS_RUNNING = 'running';
public const STATUS_WAITING = 'waiting';
public const STATUS_PAUSED = 'paused';
public const STATUS_COMPLETED = 'completed';
public const STATUS_FAILED = 'failed';
protected $fillable = [
'subject_type', 'subject_id', 'pipeline', 'current_step', 'status',
'attempt', 'max_attempts', 'next_attempt_at', 'started_at', 'finished_at',
'error', 'context',
];
protected function casts(): array
{
return [
'context' => 'array',
'next_attempt_at' => 'datetime',
'started_at' => 'datetime',
'finished_at' => 'datetime',
'current_step' => 'integer',
'attempt' => 'integer',
'max_attempts' => 'integer',
];
}
public function subject(): MorphTo
{
return $this->morphTo();
}
/**
* Runs that have not finished one way or the other.
*
* The four statuses that mean "this will do more work" were written out at
* four call sites that ask the same question — and a fifth status added to the
* list above would have had to be remembered at every one of them. What the
* callers do with the answer differs, and App\Provisioning\WorkInFlight is
* where the difference is explained.
*
* @param \Illuminate\Database\Eloquent\Builder<self> $query
*/
public function scopeInFlight($query): void
{
$query->whereIn('status', [
self::STATUS_PENDING,
self::STATUS_RUNNING,
self::STATUS_WAITING,
self::STATUS_PAUSED,
]);
}
public function events(): HasMany
{
return $this->hasMany(ProvisioningStepEvent::class, 'run_id');
}
public function resources(): HasMany
{
return $this->hasMany(RunResource::class, 'run_id');
}
/** Read a single key from the json context. */
public function context(string $key, mixed $default = null): mixed
{
return data_get($this->context, $key, $default);
}
/** Merge values into the json context and persist. */
public function mergeContext(array $values): void
{
$this->context = array_merge($this->context ?? [], $values);
$this->save();
}
/** Remove a key from the json context and persist (e.g. scrubbing a secret). */
public function forgetContext(string $key): void
{
$context = $this->context ?? [];
unset($context[$key]);
$this->context = $context;
$this->save();
}
}