fix: deletions

This commit is contained in:
Andras Bacsai 2023-11-06 18:04:18 +01:00
parent 87af9e46a6
commit 149fee2452
16 changed files with 144 additions and 35 deletions

View File

@ -6,6 +6,8 @@
use App\Models\Application; use App\Models\Application;
use App\Models\ApplicationDeploymentQueue; use App\Models\ApplicationDeploymentQueue;
use App\Models\Service; use App\Models\Service;
use App\Models\ServiceApplication;
use App\Models\StandaloneMariadb;
use App\Models\StandaloneMongodb; use App\Models\StandaloneMongodb;
use App\Models\StandaloneMysql; use App\Models\StandaloneMysql;
use App\Models\StandalonePostgresql; use App\Models\StandalonePostgresql;
@ -61,77 +63,129 @@ private function cleanup_stucked_resources()
try { try {
$applications = Application::all(); $applications = Application::all();
foreach ($applications as $application) { foreach ($applications as $application) {
if (!$application->environment) { if (!data_get($application, 'environment')) {
ray('Application without environment', $application->name); ray('Application without environment', $application->name);
$application->delete(); $application->delete();
} }
if (!data_get($application, 'server')) {
ray('Application without server', $application->name);
$application->delete();
}
if (!$application->destination()) { if (!$application->destination()) {
ray('Application without destination', $application->name); ray('Application without destination', $application->name);
$application->delete(); $application->delete();
} }
} }
} catch (\Throwable $e) {
echo "Error in application: {$e->getMessage()}\n";
}
try {
$postgresqls = StandalonePostgresql::all(); $postgresqls = StandalonePostgresql::all();
foreach ($postgresqls as $postgresql) { foreach ($postgresqls as $postgresql) {
if (!$postgresql->environment) { if (!data_get($postgresql, 'environment')) {
ray('Postgresql without environment', $postgresql->name); ray('Postgresql without environment', $postgresql->name);
$postgresql->delete(); $postgresql->delete();
} }
if (!data_get($postgresql, 'server')) {
ray('Postgresql without server', $postgresql->name);
$postgresql->delete();
}
if (!$postgresql->destination()) { if (!$postgresql->destination()) {
ray('Postgresql without destination', $postgresql->name); ray('Postgresql without destination', $postgresql->name);
$postgresql->delete(); $postgresql->delete();
} }
} }
} catch (\Throwable $e) {
echo "Error in postgresql: {$e->getMessage()}\n";
}
try {
$redis = StandaloneRedis::all(); $redis = StandaloneRedis::all();
foreach ($redis as $redis) { foreach ($redis as $redis) {
if (!$redis->environment) { if (!data_get($redis, 'environment')) {
ray('Redis without environment', $redis->name); ray('Redis without environment', $redis->name);
$redis->delete(); $redis->delete();
} }
if (!data_get($redis, 'server')) {
ray('Redis without server', $redis->name);
$redis->delete();
}
if (!$redis->destination()) { if (!$redis->destination()) {
ray('Redis without destination', $redis->name); ray('Redis without destination', $redis->name);
$redis->delete(); $redis->delete();
} }
} }
} catch (\Throwable $e) {
echo "Error in redis: {$e->getMessage()}\n";
}
try {
$mongodbs = StandaloneMongodb::all(); $mongodbs = StandaloneMongodb::all();
foreach ($mongodbs as $mongodb) { foreach ($mongodbs as $mongodb) {
if (!$mongodb->environment) { if (!data_get($mongodb, 'environment')) {
ray('Mongodb without environment', $mongodb->name); ray('Mongodb without environment', $mongodb->name);
$mongodb->delete(); $mongodb->delete();
} }
if (!data_get($mongodb, 'server')) {
ray('Mongodb without server', $mongodb->name);
$mongodb->delete();
}
if (!$mongodb->destination()) { if (!$mongodb->destination()) {
ray('Mongodb without destination', $mongodb->name); ray('Mongodb without destination', $mongodb->name);
$mongodb->delete(); $mongodb->delete();
} }
} }
} catch (\Throwable $e) {
echo "Error in mongodb: {$e->getMessage()}\n";
}
try {
$mysqls = StandaloneMysql::all(); $mysqls = StandaloneMysql::all();
foreach ($mysqls as $mysql) { foreach ($mysqls as $mysql) {
if (!$mysql->environment) { if (!data_get($mysql, 'environment')) {
ray('Mysql without environment', $mysql->name); ray('Mysql without environment', $mysql->name);
$mysql->delete(); $mysql->delete();
} }
if (!data_get($mysql, 'server')) {
ray('Mysql without server', $mysql->name);
$mysql->delete();
}
if (!$mysql->destination()) { if (!$mysql->destination()) {
ray('Mysql without destination', $mysql->name); ray('Mysql without destination', $mysql->name);
$mysql->delete(); $mysql->delete();
} }
} }
$mariadbs = StandaloneMysql::all(); } catch (\Throwable $e) {
echo "Error in mysql: {$e->getMessage()}\n";
}
try {
$mariadbs = StandaloneMariadb::all();
foreach ($mariadbs as $mariadb) { foreach ($mariadbs as $mariadb) {
if (!$mariadb->environment) { if (!data_get($mariadb, 'environment')) {
ray('Mariadb without environment', $mariadb->name); ray('Mariadb without environment', $mariadb->name);
$mariadb->delete(); $mariadb->delete();
} }
if (!data_get($mariadb, 'server')) {
ray('Mariadb without server', $mariadb->name);
$mariadb->delete();
}
if (!$mariadb->destination()) { if (!$mariadb->destination()) {
ray('Mariadb without destination', $mariadb->name); ray('Mariadb without destination', $mariadb->name);
$mariadb->delete(); $mariadb->delete();
} }
} }
} catch (\Throwable $e) {
echo "Error in mariadb: {$e->getMessage()}\n";
}
try {
$services = Service::all(); $services = Service::all();
foreach ($services as $service) { foreach ($services as $service) {
if (!$service->environment) { if (!data_get($service, 'environment')) {
ray('Service without environment', $service->name); ray('Service without environment', $service->name);
$service->delete(); $service->delete();
} }
if (!$service->server) { if (!data_get($service, 'server')) {
ray('Service without server', $service->name); ray('Service without server', $service->name);
$service->delete(); $service->delete();
} }
@ -141,7 +195,18 @@ private function cleanup_stucked_resources()
} }
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
echo "Error: {$e->getMessage()}\n"; echo "Error in service: {$e->getMessage()}\n";
}
try {
$serviceApplications = ServiceApplication::all();
foreach ($serviceApplications as $service) {
if (!data_get($service, 'service')) {
ray('ServiceApplication without service', $service->name);
$service->delete();
}
}
} catch (\Throwable $e) {
echo "Error in serviceApplications: {$e->getMessage()}\n";
} }
} }
} }

View File

@ -14,7 +14,7 @@ public function delete()
{ {
try { try {
$this->authorize('delete', $this->server); $this->authorize('delete', $this->server);
if (!$this->server->isEmpty()) { if ($this->server->hasDefinedResources()) {
$this->emit('error', 'Server has defined resources. Please delete them first.'); $this->emit('error', 'Server has defined resources. Please delete them first.');
return; return;
} }

View File

@ -34,8 +34,11 @@ protected static function booted()
static::deleting(function ($application) { static::deleting(function ($application) {
$application->settings()->delete(); $application->settings()->delete();
$storages = $application->persistentStorages()->get(); $storages = $application->persistentStorages()->get();
foreach ($storages as $storage) { $server = data_get($application, 'destination.server');
instant_remote_process(["docker volume rm -f $storage->name"], $application->destination->server, false); 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();

View File

@ -109,11 +109,12 @@ public function scopeWithProxy(): Builder
return $this->proxy->modelScope(); return $this->proxy->modelScope();
} }
public function isEmpty() public function hasDefinedResources()
{ {
$applications = $this->applications()->count() === 0; $applications = $this->applications()->count() === 0;
$databases = $this->databases()->count() === 0; $databases = $this->databases()->count() === 0;
if ($applications && $databases) { $services = $this->services()->count() === 0;
if ($applications || $databases || $services) {
return true; return true;
} }
return false; return false;

View File

@ -5,7 +5,6 @@
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\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@ -23,21 +22,21 @@ protected static function booted()
foreach ($storages as $storage) { foreach ($storages as $storage) {
$storagesToDelete->push($storage); $storagesToDelete->push($storage);
} }
$application->persistentStorages()->delete();
} }
foreach ($service->databases()->get() as $database) { foreach ($service->databases()->get() as $database) {
$storages = $database->persistentStorages()->get(); $storages = $database->persistentStorages()->get();
foreach ($storages as $storage) { foreach ($storages as $storage) {
$storagesToDelete->push($storage); $storagesToDelete->push($storage);
} }
$database->persistentStorages()->delete();
} }
$service->environment_variables()->delete(); $service->environment_variables()->delete();
$service->applications()->delete(); $service->applications()->delete();
$service->databases()->delete(); $service->databases()->delete();
if ($storagesToDelete->count() > 0) {
$storagesToDelete->each(function ($storage) use ($service) { $server = data_get($service, 'server');
instant_remote_process(["docker volume rm -f $storage->name"], $service->server, false); if ($server && $storagesToDelete->count() > 0) {
$storagesToDelete->each(function ($storage) use ($server) {
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
}); });
} }
}); });

View File

@ -11,6 +11,13 @@ class ServiceApplication extends BaseModel
use HasFactory; use HasFactory;
protected $guarded = []; protected $guarded = [];
protected static function booted()
{
static::deleting(function ($service) {
$service->persistentStorages()->delete();
$service->fileStorages()->delete();
});
}
public function type() public function type()
{ {
return 'service'; return 'service';

View File

@ -9,6 +9,13 @@ class ServiceDatabase extends BaseModel
use HasFactory; use HasFactory;
protected $guarded = []; protected $guarded = [];
protected static function booted()
{
static::deleting(function ($service) {
$service->persistentStorages()->delete();
$service->fileStorages()->delete();
});
}
public function type() public function type()
{ {
return 'service'; return 'service';

View File

@ -30,8 +30,11 @@ protected static function booted()
}); });
static::deleting(function ($database) { static::deleting(function ($database) {
$storages = $database->persistentStorages()->get(); $storages = $database->persistentStorages()->get();
foreach ($storages as $storage) { $server = data_get($database, 'destination.server');
instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); if ($server) {
foreach ($storages as $storage) {
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
}
} }
$database->scheduledBackups()->delete(); $database->scheduledBackups()->delete();
$database->persistentStorages()->delete(); $database->persistentStorages()->delete();

View File

@ -33,8 +33,11 @@ protected static function booted()
}); });
static::deleting(function ($database) { static::deleting(function ($database) {
$storages = $database->persistentStorages()->get(); $storages = $database->persistentStorages()->get();
foreach ($storages as $storage) { $server = data_get($database, 'destination.server');
instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); if ($server) {
foreach ($storages as $storage) {
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
}
} }
$database->scheduledBackups()->delete(); $database->scheduledBackups()->delete();
$database->persistentStorages()->delete(); $database->persistentStorages()->delete();

View File

@ -30,8 +30,11 @@ protected static function booted()
}); });
static::deleting(function ($database) { static::deleting(function ($database) {
$storages = $database->persistentStorages()->get(); $storages = $database->persistentStorages()->get();
foreach ($storages as $storage) { $server = data_get($database, 'destination.server');
instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); if ($server) {
foreach ($storages as $storage) {
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
}
} }
$database->scheduledBackups()->delete(); $database->scheduledBackups()->delete();
$database->persistentStorages()->delete(); $database->persistentStorages()->delete();

View File

@ -30,8 +30,11 @@ protected static function booted()
}); });
static::deleting(function ($database) { static::deleting(function ($database) {
$storages = $database->persistentStorages()->get(); $storages = $database->persistentStorages()->get();
foreach ($storages as $storage) { $server = data_get($database, 'destination.server');
instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); if ($server) {
foreach ($storages as $storage) {
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
}
} }
$database->scheduledBackups()->delete(); $database->scheduledBackups()->delete();
$database->persistentStorages()->delete(); $database->persistentStorages()->delete();

View File

@ -26,8 +26,11 @@ protected static function booted()
static::deleting(function ($database) { static::deleting(function ($database) {
$database->scheduledBackups()->delete(); $database->scheduledBackups()->delete();
$storages = $database->persistentStorages()->get(); $storages = $database->persistentStorages()->get();
foreach ($storages as $storage) { $server = data_get($database, 'destination.server');
instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); if ($server) {
foreach ($storages as $storage) {
instant_remote_process(["docker volume rm -f $storage->name"], $server, false);
}
} }
$database->persistentStorages()->delete(); $database->persistentStorages()->delete();
$database->environment_variables()->delete(); $database->environment_variables()->delete();

View File

@ -60,6 +60,14 @@ services:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- /data/coolify/:/data/coolify - /data/coolify/:/data/coolify
# - coolify-data-dev:/data/coolify # - coolify-data-dev:/data/coolify
remote-host:
<<: *testing-host-base
container_name: coolify-remote-host
volumes:
- /:/host
- /var/run/docker.sock:/var/run/docker.sock
- /data/coolify/:/data/coolify
# - coolify-data-dev:/data/coolify
mailpit: mailpit:
image: "axllent/mailpit:latest" image: "axllent/mailpit:latest"
container_name: coolify-mail container_name: coolify-mail

View File

@ -11,8 +11,12 @@
<div class="pb-4">This will remove this server from Coolify. Beware! There is no coming <div class="pb-4">This will remove this server from Coolify. Beware! There is no coming
back! back!
</div> </div>
<x-forms.button isError isModal modalId="deleteServer"> @if ($server->hasDefinedResources())
Delete <div class="text-warning">Please delete all resources before deleting this server.</div>
</x-forms.button> @else
<x-forms.button isError isModal modalId="deleteServer">
Delete
</x-forms.button>
@endif
@endif @endif
</div> </div>

View File

@ -62,7 +62,6 @@
helper="Disk cleanup job will be executed if disk usage is more than this number." /> helper="Disk cleanup job will be executed if disk usage is more than this number." />
@endif @endif
</form> </form>
<livewire:server.delete :server="$server" />
<script> <script>
Livewire.on('installDocker', () => { Livewire.on('installDocker', () => {
installDocker.showModal(); installDocker.showModal();

View File

@ -11,4 +11,5 @@
</x-modal> </x-modal>
<x-server.navbar :server="$server" :parameters="$parameters" /> <x-server.navbar :server="$server" :parameters="$parameters" />
<livewire:server.form :server="$server" /> <livewire:server.form :server="$server" />
<livewire:server.delete :server="$server" />
</div> </div>