fix/feat: better volume cleanups
This commit is contained in:
parent
36c4be1d17
commit
2b805f869a
@ -43,9 +43,6 @@ public function handle(Application $application)
|
|||||||
$uuid = $application->uuid;
|
$uuid = $application->uuid;
|
||||||
instant_remote_process(["docker network disconnect {$uuid} coolify-proxy"], $server, false);
|
instant_remote_process(["docker network disconnect {$uuid} coolify-proxy"], $server, false);
|
||||||
instant_remote_process(["docker network rm {$uuid}"], $server, false);
|
instant_remote_process(["docker network rm {$uuid}"], $server, false);
|
||||||
|
|
||||||
// remove volumes
|
|
||||||
instant_remote_process(["cd {$application->dirOnServer()} && docker compose down -v"], $server, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1240,6 +1240,16 @@ public function application_by_uuid(Request $request)
|
|||||||
format: 'uuid',
|
format: 'uuid',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
new OA\Parameter(
|
||||||
|
name: 'cleanup',
|
||||||
|
in: 'query',
|
||||||
|
description: 'Delete configurations and volumes.',
|
||||||
|
required: false,
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
)
|
||||||
|
),
|
||||||
],
|
],
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
@ -1273,7 +1283,7 @@ public function application_by_uuid(Request $request)
|
|||||||
public function delete_by_uuid(Request $request)
|
public function delete_by_uuid(Request $request)
|
||||||
{
|
{
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
$cleanup = $request->query->get('cleanup') ?? false;
|
$cleanup = $request->query->get('cleanup') ?? true;
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
}
|
}
|
||||||
@ -1287,7 +1297,7 @@ public function delete_by_uuid(Request $request)
|
|||||||
'message' => 'Application not found',
|
'message' => 'Application not found',
|
||||||
], 404);
|
], 404);
|
||||||
}
|
}
|
||||||
DeleteResourceJob::dispatch($application, $cleanup);
|
DeleteResourceJob::dispatch($application, deleteConfigurations: $cleanup, deleteVolumes: $cleanup);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Application deletion request queued.',
|
'message' => 'Application deletion request queued.',
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
use App\Actions\Database\StopDatabaseProxy;
|
use App\Actions\Database\StopDatabaseProxy;
|
||||||
use App\Enums\NewDatabaseTypes;
|
use App\Enums\NewDatabaseTypes;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Jobs\DeleteResourceJob;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@ -1528,6 +1529,16 @@ public function create_database(Request $request, NewDatabaseTypes $type)
|
|||||||
format: 'uuid',
|
format: 'uuid',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
new OA\Parameter(
|
||||||
|
name: 'cleanup',
|
||||||
|
in: 'query',
|
||||||
|
description: 'Delete configurations and volumes.',
|
||||||
|
required: false,
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
)
|
||||||
|
),
|
||||||
],
|
],
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
@ -1561,6 +1572,7 @@ public function create_database(Request $request, NewDatabaseTypes $type)
|
|||||||
public function delete_by_uuid(Request $request)
|
public function delete_by_uuid(Request $request)
|
||||||
{
|
{
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
|
$cleanup = $request->query->get('cleanup') ?? true;
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
}
|
}
|
||||||
@ -1571,8 +1583,7 @@ public function delete_by_uuid(Request $request)
|
|||||||
if (! $database) {
|
if (! $database) {
|
||||||
return response()->json(['message' => 'Database not found.'], 404);
|
return response()->json(['message' => 'Database not found.'], 404);
|
||||||
}
|
}
|
||||||
StopDatabase::dispatch($database);
|
DeleteResourceJob::dispatch($database, deleteConfigurations: $cleanup, deleteVolumes: $cleanup);
|
||||||
$database->forceDelete();
|
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Database deletion request queued.',
|
'message' => 'Database deletion request queued.',
|
||||||
|
@ -28,14 +28,15 @@ class DeleteResourceJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
public function __construct(public Application|Service|StandalonePostgresql|StandaloneRedis|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $resource, public bool $deleteConfigurations = false) {}
|
public function __construct(public Application|Service|StandalonePostgresql|StandaloneRedis|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $resource, public bool $deleteConfigurations = false, public bool $deleteVolumes = false) {}
|
||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->resource->forceDelete();
|
$persistentStorages = collect();
|
||||||
switch ($this->resource->type()) {
|
switch ($this->resource->type()) {
|
||||||
case 'application':
|
case 'application':
|
||||||
|
$persistentStorages = $this->resource?->persistentStorages()?->get();
|
||||||
StopApplication::run($this->resource);
|
StopApplication::run($this->resource);
|
||||||
break;
|
break;
|
||||||
case 'standalone-postgresql':
|
case 'standalone-postgresql':
|
||||||
@ -46,6 +47,7 @@ public function handle()
|
|||||||
case 'standalone-keydb':
|
case 'standalone-keydb':
|
||||||
case 'standalone-dragonfly':
|
case 'standalone-dragonfly':
|
||||||
case 'standalone-clickhouse':
|
case 'standalone-clickhouse':
|
||||||
|
$persistentStorages = $this->resource?->persistentStorages()?->get();
|
||||||
StopDatabase::run($this->resource);
|
StopDatabase::run($this->resource);
|
||||||
break;
|
break;
|
||||||
case 'service':
|
case 'service':
|
||||||
@ -53,6 +55,10 @@ public function handle()
|
|||||||
DeleteService::run($this->resource);
|
DeleteService::run($this->resource);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->deleteVolumes && $this->resource->type() !== 'service') {
|
||||||
|
$this->resource?->delete_volumes($persistentStorages);
|
||||||
|
}
|
||||||
if ($this->deleteConfigurations) {
|
if ($this->deleteConfigurations) {
|
||||||
$this->resource?->delete_configurations();
|
$this->resource?->delete_configurations();
|
||||||
}
|
}
|
||||||
@ -61,6 +67,7 @@ public function handle()
|
|||||||
send_internal_notification('ContainerStoppingJob failed with: '.$e->getMessage());
|
send_internal_notification('ContainerStoppingJob failed with: '.$e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
} finally {
|
} finally {
|
||||||
|
$this->resource->forceDelete();
|
||||||
Artisan::queue('cleanup:stucked-resources');
|
Artisan::queue('cleanup:stucked-resources');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@ class Danger extends Component
|
|||||||
|
|
||||||
public bool $delete_configurations = true;
|
public bool $delete_configurations = true;
|
||||||
|
|
||||||
|
public bool $delete_volumes = true;
|
||||||
|
|
||||||
public ?string $modalId = null;
|
public ?string $modalId = null;
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
@ -31,7 +33,7 @@ public function delete()
|
|||||||
try {
|
try {
|
||||||
// $this->authorize('delete', $this->resource);
|
// $this->authorize('delete', $this->resource);
|
||||||
$this->resource->delete();
|
$this->resource->delete();
|
||||||
DeleteResourceJob::dispatch($this->resource, $this->delete_configurations);
|
DeleteResourceJob::dispatch($this->resource, $this->delete_configurations, $this->delete_volumes);
|
||||||
|
|
||||||
return redirect()->route('project.resource.index', [
|
return redirect()->route('project.resource.index', [
|
||||||
'project_uuid' => $this->projectUuid,
|
'project_uuid' => $this->projectUuid,
|
||||||
|
@ -126,16 +126,9 @@ protected static function booted()
|
|||||||
$application->compose_parsing_version = '2';
|
$application->compose_parsing_version = '2';
|
||||||
$application->save();
|
$application->save();
|
||||||
});
|
});
|
||||||
static::deleting(function ($application) {
|
static::forceDeleting(function ($application) {
|
||||||
$application->update(['fqdn' => null]);
|
$application->update(['fqdn' => null]);
|
||||||
$application->settings()->delete();
|
$application->settings()->delete();
|
||||||
$storages = $application->persistentStorages()->get();
|
|
||||||
$server = data_get($application, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$application->persistentStorages()->delete();
|
$application->persistentStorages()->delete();
|
||||||
$application->environment_variables()->delete();
|
$application->environment_variables()->delete();
|
||||||
$application->environment_variables_preview()->delete();
|
$application->environment_variables_preview()->delete();
|
||||||
@ -161,6 +154,23 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(?Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($this->build_pack === 'dockercompose') {
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
ray('Deleting volumes');
|
||||||
|
instant_remote_process(["cd {$this->dirOnServer()} && docker compose down -v"], $server, false);
|
||||||
|
} else {
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function additional_servers()
|
public function additional_servers()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Server::class, 'additional_destinations')
|
return $this->belongsToMany(Server::class, 'additional_destinations')
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -31,16 +32,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -91,6 +85,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -31,16 +32,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -91,6 +85,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -31,16 +32,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -91,6 +85,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -31,16 +32,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -91,6 +85,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -35,16 +36,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -95,6 +89,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -32,16 +33,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -92,6 +86,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -32,16 +33,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -61,6 +55,18 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
ray('Deleting volume: '.$storage->name);
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function isConfigurationChanged(bool $save = false)
|
public function isConfigurationChanged(bool $save = false)
|
||||||
{
|
{
|
||||||
$newConfigHash = $this->image.$this->ports_mappings.$this->postgres_initdb_args.$this->postgres_host_auth_method;
|
$newConfigHash = $this->image.$this->ports_mappings.$this->postgres_initdb_args.$this->postgres_host_auth_method;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -27,16 +28,9 @@ protected static function booted()
|
|||||||
'is_readonly' => true,
|
'is_readonly' => true,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($database) {
|
static::forceDeleting(function ($database) {
|
||||||
$database->scheduledBackups()->delete();
|
|
||||||
$storages = $database->persistentStorages()->get();
|
|
||||||
$server = data_get($database, 'destination.server');
|
|
||||||
if ($server) {
|
|
||||||
foreach ($storages as $storage) {
|
|
||||||
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$database->persistentStorages()->delete();
|
$database->persistentStorages()->delete();
|
||||||
|
$database->scheduledBackups()->delete();
|
||||||
$database->environment_variables()->delete();
|
$database->environment_variables()->delete();
|
||||||
$database->tags()->detach();
|
$database->tags()->detach();
|
||||||
});
|
});
|
||||||
@ -87,6 +81,17 @@ public function delete_configurations()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete_volumes(Collection $persistentStorages)
|
||||||
|
{
|
||||||
|
if ($persistentStorages->count() === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$server = data_get($this, 'destination.server');
|
||||||
|
foreach ($persistentStorages as $storage) {
|
||||||
|
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function realStatus()
|
public function realStatus()
|
||||||
{
|
{
|
||||||
return $this->getRawOriginal('status');
|
return $this->getRawOriginal('status');
|
||||||
|
19
openapi.yaml
19
openapi.yaml
@ -1343,6 +1343,14 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
-
|
||||||
|
name: cleanup
|
||||||
|
in: query
|
||||||
|
description: 'Delete configurations and volumes.'
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: 'Application deleted.'
|
description: 'Application deleted.'
|
||||||
@ -1799,6 +1807,14 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
-
|
||||||
|
name: cleanup
|
||||||
|
in: query
|
||||||
|
description: 'Delete configurations and volumes.'
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: 'Database deleted.'
|
description: 'Database deleted.'
|
||||||
@ -4026,6 +4042,9 @@ components:
|
|||||||
format: date-time
|
format: date-time
|
||||||
nullable: true
|
nullable: true
|
||||||
description: 'The date and time when the application was deleted.'
|
description: 'The date and time when the application was deleted.'
|
||||||
|
compose_parsing_version:
|
||||||
|
type: string
|
||||||
|
description: 'How Coolify parse the compose file.'
|
||||||
type: object
|
type: object
|
||||||
ApplicationDeploymentQueue:
|
ApplicationDeploymentQueue:
|
||||||
description: 'Project model'
|
description: 'Project model'
|
||||||
|
@ -11,5 +11,6 @@
|
|||||||
<h4>Actions</h4>
|
<h4>Actions</h4>
|
||||||
<x-forms.checkbox id="delete_configurations"
|
<x-forms.checkbox id="delete_configurations"
|
||||||
label="Permanently delete configuration files from the server?"></x-forms.checkbox>
|
label="Permanently delete configuration files from the server?"></x-forms.checkbox>
|
||||||
|
<x-forms.checkbox id="delete_volumes" label="Permanently delete associated volumes?"></x-forms.checkbox>
|
||||||
</x-modal-confirmation>
|
</x-modal-confirmation>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user