Merge branch 'next' into vaultwarden-fix
This commit is contained in:
commit
ba4be02e75
@ -1,3 +1,6 @@
|
|||||||
|
[![Bounty Issues](https://img.shields.io/static/v1?labelColor=grey&color=6366f1&label=Algora&message=%F0%9F%92%8E+Bounty+issues&style=for-the-badge)](https://console.algora.io/org/coollabsio/bounties/new)
|
||||||
|
[![Open Bounties](https://img.shields.io/endpoint?url=https%3A%2F%2Fconsole.algora.io%2Fapi%2Fshields%2Fcoollabsio%2Fbounties%3Fstatus%3Dopen&style=for-the-badge)](https://console.algora.io/org/coollabsio/bounties?status=open)
|
||||||
|
[![Rewarded Bounties](https://img.shields.io/endpoint?url=https%3A%2F%2Fconsole.algora.io%2Fapi%2Fshields%2Fcoollabsio%2Fbounties%3Fstatus%3Dcompleted&style=for-the-badge)](https://console.algora.io/org/coollabsio/bounties?status=completed)
|
||||||
# About the Project
|
# About the Project
|
||||||
|
|
||||||
Coolify is an open-source & self-hostable alternative to Heroku / Netlify / Vercel / etc.
|
Coolify is an open-source & self-hostable alternative to Heroku / Netlify / Vercel / etc.
|
||||||
|
@ -29,6 +29,7 @@ public function handle(StandaloneClickhouse $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
|
|
||||||
@ -93,6 +94,11 @@ public function handle(StandaloneClickhouse $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ public function handle(StandaloneDragonfly $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
|
|
||||||
@ -94,6 +95,11 @@ public function handle(StandaloneDragonfly $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ public function handle(StandaloneKeydb $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
$this->add_custom_keydb();
|
$this->add_custom_keydb();
|
||||||
@ -92,6 +93,11 @@ public function handle(StandaloneKeydb $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public function handle(StandaloneMariadb $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
$this->add_custom_mysql();
|
$this->add_custom_mysql();
|
||||||
@ -86,6 +87,11 @@ public function handle(StandaloneMariadb $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ public function handle(StandaloneMongodb $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
$this->add_custom_mongo_conf();
|
$this->add_custom_mongo_conf();
|
||||||
@ -94,6 +95,11 @@ public function handle(StandaloneMongodb $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public function handle(StandaloneMysql $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
$this->add_custom_mysql();
|
$this->add_custom_mysql();
|
||||||
@ -86,6 +87,11 @@ public function handle(StandaloneMysql $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ public function handle(StandalonePostgresql $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
$this->generate_init_scripts();
|
$this->generate_init_scripts();
|
||||||
@ -92,6 +93,11 @@ public function handle(StandalonePostgresql $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ public function handle(StandaloneRedis $database)
|
|||||||
];
|
];
|
||||||
|
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->database->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
$environment_variables = $this->generate_environment_variables();
|
$environment_variables = $this->generate_environment_variables();
|
||||||
$this->add_custom_redis();
|
$this->add_custom_redis();
|
||||||
@ -96,6 +97,11 @@ public function handle(StandaloneRedis $database)
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,10 @@ public function events(Request $request)
|
|||||||
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
|
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
|
||||||
}
|
}
|
||||||
if (!$subscription) {
|
if (!$subscription) {
|
||||||
|
if ($status === 'incomplete_expired') {
|
||||||
|
send_internal_notification('Subscription incomplete expired for customer: ' . $customerId);
|
||||||
|
return response("Subscription incomplete expired", 200);
|
||||||
|
}
|
||||||
send_internal_notification('No subscription found for: ' . $customerId);
|
send_internal_notification('No subscription found for: ' . $customerId);
|
||||||
return response("No subscription found", 400);
|
return response("No subscription found", 400);
|
||||||
}
|
}
|
||||||
@ -166,9 +170,11 @@ public function events(Request $request)
|
|||||||
$quantity = data_get($data, 'items.data.0.quantity', 10);
|
$quantity = data_get($data, 'items.data.0.quantity', 10);
|
||||||
}
|
}
|
||||||
$team = data_get($subscription, 'team');
|
$team = data_get($subscription, 'team');
|
||||||
$team->update([
|
if ($team) {
|
||||||
'custom_server_limit' => $quantity,
|
$team->update([
|
||||||
]);
|
'custom_server_limit' => $quantity,
|
||||||
|
]);
|
||||||
|
}
|
||||||
ServerLimitCheckJob::dispatch($team);
|
ServerLimitCheckJob::dispatch($team);
|
||||||
}
|
}
|
||||||
$subscription->update([
|
$subscription->update([
|
||||||
@ -210,7 +216,9 @@ public function events(Request $request)
|
|||||||
$customerId = data_get($data, 'customer');
|
$customerId = data_get($data, 'customer');
|
||||||
$subscription = Subscription::where('stripe_customer_id', $customerId)->firstOrFail();
|
$subscription = Subscription::where('stripe_customer_id', $customerId)->firstOrFail();
|
||||||
$team = data_get($subscription, 'team');
|
$team = data_get($subscription, 'team');
|
||||||
$team->trialEnded();
|
if ($team) {
|
||||||
|
$team->trialEnded();
|
||||||
|
}
|
||||||
$subscription->update([
|
$subscription->update([
|
||||||
'stripe_subscription_id' => null,
|
'stripe_subscription_id' => null,
|
||||||
'stripe_plan_id' => null,
|
'stripe_plan_id' => null,
|
||||||
|
@ -1359,6 +1359,7 @@ private function generate_compose_file()
|
|||||||
$onlyPort = $ports[0];
|
$onlyPort = $ports[0];
|
||||||
}
|
}
|
||||||
$persistent_storages = $this->generate_local_persistent_volumes();
|
$persistent_storages = $this->generate_local_persistent_volumes();
|
||||||
|
$persistent_file_volumes = $this->application->fileStorages()->get();
|
||||||
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
|
||||||
// $environment_variables = $this->generate_environment_variables($ports);
|
// $environment_variables = $this->generate_environment_variables($ports);
|
||||||
$this->save_environment_variables();
|
$this->save_environment_variables();
|
||||||
@ -1559,6 +1560,11 @@ private function generate_compose_file()
|
|||||||
if (count($persistent_storages) > 0) {
|
if (count($persistent_storages) > 0) {
|
||||||
$docker_compose['services'][$this->container_name]['volumes'] = $persistent_storages;
|
$docker_compose['services'][$this->container_name]['volumes'] = $persistent_storages;
|
||||||
}
|
}
|
||||||
|
if (count($persistent_file_volumes) > 0) {
|
||||||
|
$docker_compose['services'][$this->container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
|
||||||
|
return "$item->fs_path:$item->mount_path";
|
||||||
|
})->toArray();
|
||||||
|
}
|
||||||
if (count($volume_names) > 0) {
|
if (count($volume_names) > 0) {
|
||||||
$docker_compose['volumes'] = $volume_names;
|
$docker_compose['volumes'] = $volume_names;
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,17 @@ public function handle()
|
|||||||
if (config('coolify.is_sentinel_enabled')) {
|
if (config('coolify.is_sentinel_enabled')) {
|
||||||
$this->server->checkSentinel();
|
$this->server->checkSentinel();
|
||||||
}
|
}
|
||||||
$this->check_docker_engine();
|
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage());
|
send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage());
|
||||||
ray($e->getMessage());
|
ray($e->getMessage());
|
||||||
return handleError($e);
|
return handleError($e);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
// $this->check_docker_engine();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private function check_docker_engine()
|
private function check_docker_engine()
|
||||||
{
|
{
|
||||||
|
@ -7,13 +7,20 @@
|
|||||||
use App\Models\ServiceApplication;
|
use App\Models\ServiceApplication;
|
||||||
use App\Models\ServiceDatabase;
|
use App\Models\ServiceDatabase;
|
||||||
use App\Models\StandaloneClickhouse;
|
use App\Models\StandaloneClickhouse;
|
||||||
|
use App\Models\StandaloneDragonfly;
|
||||||
|
use App\Models\StandaloneKeydb;
|
||||||
|
use App\Models\StandaloneMariadb;
|
||||||
|
use App\Models\StandaloneMongodb;
|
||||||
|
use App\Models\StandaloneMysql;
|
||||||
|
use App\Models\StandalonePostgresql;
|
||||||
|
use App\Models\StandaloneRedis;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class FileStorage extends Component
|
class FileStorage extends Component
|
||||||
{
|
{
|
||||||
public LocalFileVolume $fileStorage;
|
public LocalFileVolume $fileStorage;
|
||||||
public ServiceApplication|ServiceDatabase|StandaloneClickhouse|Application $resource;
|
public ServiceApplication|StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|ServiceDatabase|Application $resource;
|
||||||
public string $fs_path;
|
public string $fs_path;
|
||||||
public ?string $workdir = null;
|
public ?string $workdir = null;
|
||||||
|
|
||||||
@ -27,7 +34,7 @@ public function mount()
|
|||||||
{
|
{
|
||||||
$this->resource = $this->fileStorage->service;
|
$this->resource = $this->fileStorage->service;
|
||||||
if (Str::of($this->fileStorage->fs_path)->startsWith('.')) {
|
if (Str::of($this->fileStorage->fs_path)->startsWith('.')) {
|
||||||
$this->workdir = $this->resource->service->workdir();
|
$this->workdir = $this->resource->service?->workdir();
|
||||||
$this->fs_path = Str::of($this->fileStorage->fs_path)->after('.');
|
$this->fs_path = Str::of($this->fileStorage->fs_path)->after('.');
|
||||||
} else {
|
} else {
|
||||||
$this->workdir = null;
|
$this->workdir = null;
|
||||||
|
@ -3,21 +3,31 @@
|
|||||||
namespace App\Livewire\Project\Shared\Storages;
|
namespace App\Livewire\Project\Shared\Storages;
|
||||||
|
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
|
use App\Models\LocalFileVolume;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Add extends Component
|
class Add extends Component
|
||||||
{
|
{
|
||||||
|
public $resource;
|
||||||
public $uuid;
|
public $uuid;
|
||||||
public $parameters;
|
public $parameters;
|
||||||
public $isSwarm = false;
|
public $isSwarm = false;
|
||||||
public string $name;
|
public string $name;
|
||||||
public string $mount_path;
|
public string $mount_path;
|
||||||
public ?string $host_path = null;
|
public ?string $host_path = null;
|
||||||
|
public string $file_storage_path;
|
||||||
|
public ?string $file_storage_content = null;
|
||||||
|
public string $file_storage_directory_source;
|
||||||
|
public string $file_storage_directory_destination;
|
||||||
|
|
||||||
public $rules = [
|
public $rules = [
|
||||||
'name' => 'required|string',
|
'name' => 'required|string',
|
||||||
'mount_path' => 'required|string',
|
'mount_path' => 'required|string',
|
||||||
'host_path' => 'string|nullable',
|
'host_path' => 'string|nullable',
|
||||||
|
'file_storage_path' => 'string',
|
||||||
|
'file_storage_content' => 'nullable|string',
|
||||||
|
'file_storage_directory_source' => 'string',
|
||||||
|
'file_storage_directory_destination' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $listeners = ['clearAddStorage' => 'clear'];
|
protected $listeners = ['clearAddStorage' => 'clear'];
|
||||||
@ -26,10 +36,16 @@ class Add extends Component
|
|||||||
'name' => 'name',
|
'name' => 'name',
|
||||||
'mount_path' => 'mount',
|
'mount_path' => 'mount',
|
||||||
'host_path' => 'host',
|
'host_path' => 'host',
|
||||||
|
'file_storage_path' => 'file storage path',
|
||||||
|
'file_storage_content' => 'file storage content',
|
||||||
|
'file_storage_directory_source' => 'file storage directory source',
|
||||||
|
'file_storage_directory_destination' => 'file storage directory destination',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->file_storage_directory_source = application_configuration_dir() . "/{$this->resource->uuid}";
|
||||||
|
$this->uuid = $this->resource->uuid;
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
if (data_get($this->parameters, 'application_uuid')) {
|
if (data_get($this->parameters, 'application_uuid')) {
|
||||||
$applicationUuid = $this->parameters['application_uuid'];
|
$applicationUuid = $this->parameters['application_uuid'];
|
||||||
@ -43,18 +59,75 @@ public function mount()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public function submitFileStorage()
|
||||||
public function submit()
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->validate($this->rules);
|
$this->validate([
|
||||||
|
'file_storage_path' => 'string',
|
||||||
|
'file_storage_content' => 'nullable|string',
|
||||||
|
]);
|
||||||
|
$this->file_storage_path = trim($this->file_storage_path);
|
||||||
|
$this->file_storage_path = str($this->file_storage_path)->start('/')->value();
|
||||||
|
if ($this->resource->getMorphClass() === 'App\Models\Application') {
|
||||||
|
$fs_path = application_configuration_dir() . '/' . $this->resource->uuid . $this->file_storage_path;
|
||||||
|
}
|
||||||
|
LocalFileVolume::create(
|
||||||
|
[
|
||||||
|
'fs_path' => $fs_path,
|
||||||
|
'mount_path' => $this->file_storage_path,
|
||||||
|
'content' => $this->file_storage_content,
|
||||||
|
'is_directory' => false,
|
||||||
|
'resource_id' => $this->resource->id,
|
||||||
|
'resource_type' => get_class($this->resource)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
$this->dispatch('refresh_storages');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public function submitFileStorageDirectory()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->validate([
|
||||||
|
'file_storage_directory_source' => 'string',
|
||||||
|
'file_storage_directory_destination' => 'string',
|
||||||
|
]);
|
||||||
|
$this->file_storage_directory_source = trim($this->file_storage_directory_source);
|
||||||
|
$this->file_storage_directory_source = str($this->file_storage_directory_source)->start('/')->value();
|
||||||
|
$this->file_storage_directory_destination = trim($this->file_storage_directory_destination);
|
||||||
|
$this->file_storage_directory_destination = str($this->file_storage_directory_destination)->start('/')->value();
|
||||||
|
LocalFileVolume::create(
|
||||||
|
[
|
||||||
|
'fs_path' => $this->file_storage_directory_source,
|
||||||
|
'mount_path' => $this->file_storage_directory_destination,
|
||||||
|
'is_directory' => true,
|
||||||
|
'resource_id' => $this->resource->id,
|
||||||
|
'resource_type' => get_class($this->resource)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
$this->dispatch('refresh_storages');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public function submitPersistentVolume()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->validate([
|
||||||
|
'name' => 'required|string',
|
||||||
|
'mount_path' => 'required|string',
|
||||||
|
'host_path' => 'string|nullable',
|
||||||
|
]);
|
||||||
$name = $this->uuid . '-' . $this->name;
|
$name = $this->uuid . '-' . $this->name;
|
||||||
$this->dispatch('addNewVolume', [
|
$this->dispatch('addNewVolume', [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'mount_path' => $this->mount_path,
|
'mount_path' => $this->mount_path,
|
||||||
'host_path' => $this->host_path,
|
'host_path' => $this->host_path,
|
||||||
]);
|
]);
|
||||||
$this->dispatch('closeStorageModal');
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ class Show extends Component
|
|||||||
public bool $isReadOnly = false;
|
public bool $isReadOnly = false;
|
||||||
public ?string $modalId = null;
|
public ?string $modalId = null;
|
||||||
public bool $isFirst = true;
|
public bool $isFirst = true;
|
||||||
|
public bool $isService = false;
|
||||||
|
public ?string $startedAt = null;
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'storage.name' => 'required|string',
|
'storage.name' => 'required|string',
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.287',
|
'release' => '4.0.0-beta.288',
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.287';
|
return '4.0.0-beta.288';
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
<div class="p-4 transition border rounded dark:border-coolgray-200">
|
<div class="p-4 transition border rounded dark:border-coolgray-200">
|
||||||
<div class="flex flex-col justify-center pb-4 text-sm select-text">
|
<div class="flex flex-col justify-center pb-4 text-sm select-text">
|
||||||
<h2>{{ data_get($resource, 'name', 'unknown') }}</h2>
|
@if (data_get($resource, 'build_pack') === 'dockercompose')
|
||||||
<div>{{ $workdir }}{{ $fs_path }} -> {{ $fileStorage->mount_path }}</div>
|
<h2>{{ data_get($resource, 'name', 'unknown') }}</h2>
|
||||||
@if ($fileStorage->is_directory)
|
|
||||||
<div class="text-xs">Directory</div>
|
|
||||||
@else
|
|
||||||
<div class="text-xs">File</div>
|
|
||||||
@endif
|
@endif
|
||||||
|
@if ($fileStorage->is_directory)
|
||||||
|
<div class="dark:text-white">Directory Mount</div>
|
||||||
|
@else
|
||||||
|
<div class="dark:text-white">File Mount</div>
|
||||||
|
@endif
|
||||||
|
<div>{{ $workdir }}{{ $fs_path }} -> {{ $fileStorage->mount_path }}</div>
|
||||||
</div>
|
</div>
|
||||||
<form wire:submit='submit' class="flex flex-col gap-2">
|
<form wire:submit='submit' class="flex flex-col gap-2">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@ -16,7 +18,8 @@
|
|||||||
</x-modal-confirmation>
|
</x-modal-confirmation>
|
||||||
@else
|
@else
|
||||||
<x-modal-confirmation action="convertToDirectory" buttonTitle="Convert to directory">
|
<x-modal-confirmation action="convertToDirectory" buttonTitle="Convert to directory">
|
||||||
This will convert this to a directory. If it was a file, it will be deleted. It is not reversible. <br>Please think again.
|
This will convert this to a directory. If it was a file, it will be deleted. It is not reversible.
|
||||||
|
<br>Please think again.
|
||||||
</x-modal-confirmation>
|
</x-modal-confirmation>
|
||||||
@endif
|
@endif
|
||||||
<x-modal-confirmation isErrorButton buttonTitle="Delete">
|
<x-modal-confirmation isErrorButton buttonTitle="Delete">
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
volume
|
volume
|
||||||
name, example: <span class='text-helper'>-pr-1</span>" />
|
name, example: <span class='text-helper'>-pr-1</span>" />
|
||||||
@if ($resource?->build_pack !== 'dockercompose')
|
@if ($resource?->build_pack !== 'dockercompose')
|
||||||
<x-modal-input buttonTitle="+ Add" title="New Persistent Storage">
|
<x-modal-input :closeOutside="false" buttonTitle="+ Add" title="New Persistent Storage">
|
||||||
<livewire:project.shared.storages.add :uuid="$resource->uuid" />
|
<livewire:project.shared.storages.add :resource="$resource"/>
|
||||||
</x-modal-input>
|
</x-modal-input>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,18 +1,43 @@
|
|||||||
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submit'>
|
<div class="flex flex-col w-full gap-2 rounded">
|
||||||
@if ($isSwarm)
|
You can add Volumes, Files and Directories to your resources here.
|
||||||
<h5>Swarm Mode detected: You need to set a shared volume (EFS/NFS/etc) on all the worker nodes if you would
|
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitPersistentVolume'>
|
||||||
like to use a persistent volumes.</h5>
|
<h3>Volume Mount</h3>
|
||||||
@endif
|
@if ($isSwarm)
|
||||||
<x-forms.input placeholder="pv-name" id="name" label="Name" required helper="Volume name." />
|
<h5>Swarm Mode detected: You need to set a shared volume (EFS/NFS/etc) on all the worker nodes if you would
|
||||||
@if ($isSwarm)
|
like to use a persistent volumes.</h5>
|
||||||
<x-forms.input placeholder="/root" id="host_path" label="Source Path" required
|
@endif
|
||||||
|
<x-forms.input placeholder="pv-name" id="name" label="Name" required helper="Volume name." />
|
||||||
|
@if ($isSwarm)
|
||||||
|
<x-forms.input placeholder="/root" id="host_path" label="Source Path" required
|
||||||
|
helper="Directory on the host system." />
|
||||||
|
@else
|
||||||
|
<x-forms.input placeholder="/root" id="host_path" label="Source Path"
|
||||||
|
helper="Directory on the host system." />
|
||||||
|
@endif
|
||||||
|
<x-forms.input placeholder="/tmp/root" id="mount_path" label="Destination Path" required
|
||||||
|
helper="Directory inside the container." />
|
||||||
|
<x-forms.button type="submit" @click="modalOpen=false">
|
||||||
|
Save
|
||||||
|
</x-forms.button>
|
||||||
|
</form>
|
||||||
|
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorage'>
|
||||||
|
<h3>File Mount</h3>
|
||||||
|
<x-forms.input placeholder="/etc/nginx/nginx.conf" id="file_storage_path" label="Destination Path" required
|
||||||
|
helper="File inside the container" />
|
||||||
|
<x-forms.textarea label="Content" id="file_storage_content"></x-forms.textarea>
|
||||||
|
<x-forms.button type="submit" @click="modalOpen=false">
|
||||||
|
Save
|
||||||
|
</x-forms.button>
|
||||||
|
</form>
|
||||||
|
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorageDirectory'>
|
||||||
|
<h3>Directory Mount</h3>
|
||||||
|
<x-forms.input placeholder="{{ application_configuration_dir() }}/{{ $resource->uuid }}/etc/nginx"
|
||||||
|
id="file_storage_directory_source" label="Source Directory" required
|
||||||
helper="Directory on the host system." />
|
helper="Directory on the host system." />
|
||||||
@else
|
<x-forms.input placeholder="/etc/nginx" id="file_storage_directory_destination" label="Destination Directory"
|
||||||
<x-forms.input placeholder="/root" id="host_path" label="Source Path" helper="Directory on the host system." />
|
required helper="Directory inside the container." />
|
||||||
@endif
|
<x-forms.button type="submit" @click="modalOpen=false">
|
||||||
<x-forms.input placeholder="/tmp/root" id="mount_path" label="Destination Path" required
|
Save
|
||||||
helper="Directory inside the container." />
|
</x-forms.button>
|
||||||
<x-forms.button type="submit" @click="slideOverOpen=false">
|
</form>
|
||||||
Save
|
</div>
|
||||||
</x-forms.button>
|
|
||||||
</form>
|
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
@foreach ($resource->persistentStorages as $storage)
|
@foreach ($resource->persistentStorages as $storage)
|
||||||
@if ($resource->type() === 'service')
|
@if ($resource->type() === 'service')
|
||||||
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage"
|
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage"
|
||||||
:isFirst="$loop->first" isReadOnly='true' />
|
:isFirst="$loop->first" isReadOnly='true' isService='true' />
|
||||||
@else
|
@else
|
||||||
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage"
|
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage"
|
||||||
isReadOnly="{{ data_get($storage, 'is_readonly') }}" />
|
isReadOnly="{{ data_get($storage, 'is_readonly') }}"
|
||||||
|
startedAt="{{ data_get($resource, 'started_at') }}" />
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,27 +4,35 @@
|
|||||||
@if ($isFirst)
|
@if ($isFirst)
|
||||||
<x-forms.input id="storage.name" label="Volume Name" required
|
<x-forms.input id="storage.name" label="Volume Name" required
|
||||||
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
|
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||||
<x-forms.input id="storage.host_path" label="Source Path (on host)"
|
@if ($isService || $startedAt)
|
||||||
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
<x-forms.input id="storage.host_path" readonly helper="Directory on the host system."
|
||||||
<x-forms.input id="storage.mount_path" label="Destination Path (in container)" required readonly />
|
label="Source Path"
|
||||||
|
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||||
|
@else
|
||||||
|
<x-forms.input id="storage.host_path" helper="Directory on the host system." label="Source Path"
|
||||||
|
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||||
|
@endif
|
||||||
|
<x-forms.input id="storage.mount_path" label="Destination Path" helper="Directory inside the container."
|
||||||
|
required readonly />
|
||||||
<x-forms.button type="submit">
|
<x-forms.button type="submit">
|
||||||
Update
|
Update
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
@else
|
@else
|
||||||
<x-forms.input id="storage.name" required readonly
|
<x-forms.input id="storage.name" required readonly
|
||||||
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
|
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||||
<x-forms.input id="storage.host_path" readonly />
|
<x-forms.input id="storage.host_path" helper="Directory on the host system." readonly />
|
||||||
<x-forms.input id="storage.mount_path" required readonly />
|
<x-forms.input id="storage.mount_path" helper="Directory inside the container." required readonly />
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
@if ($isFirst)
|
@if ($isFirst)
|
||||||
<x-forms.input id="storage.name" label="Volume Name" required />
|
<x-forms.input id="storage.name" label="Volume Name" required />
|
||||||
<x-forms.input id="storage.host_path" label="Source Path (on host)" />
|
<x-forms.input id="storage.host_path" helper="Directory on the host system." label="Source Path" />
|
||||||
<x-forms.input id="storage.mount_path" label="Destination Path (in container)" required />
|
<x-forms.input id="storage.mount_path" label="Destination Path" helper="Directory inside the container."
|
||||||
|
required />
|
||||||
@else
|
@else
|
||||||
<x-forms.input id="storage.name" required />
|
<x-forms.input id="storage.name" required />
|
||||||
<x-forms.input id="storage.host_path" />
|
<x-forms.input id="storage.host_path" helper="Directory on the host system." />
|
||||||
<x-forms.input id="storage.mount_path" required />
|
<x-forms.input id="storage.mount_path" helper="Directory inside the container." required />
|
||||||
@endif
|
@endif
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.button type="submit">
|
<x-forms.button type="submit">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"coolify": {
|
"coolify": {
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.287"
|
"version": "4.0.0-beta.288"
|
||||||
},
|
},
|
||||||
"sentinel": {
|
"sentinel": {
|
||||||
"version": "0.0.4"
|
"version": "0.0.4"
|
||||||
|
Loading…
Reference in New Issue
Block a user