100 lines
3.0 KiB
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();
|
|
}
|
|
}
|