lots of updates + refactoring
This commit is contained in:
parent
bfc20ef219
commit
971d7f703d
@ -5,19 +5,66 @@
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use App\Models\StandalonePostgres;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class StartPostgresql
|
||||
{
|
||||
public function __invoke(Server $server, StandalonePostgres $database)
|
||||
public function __invoke(Server $server, StandalonePostgresql $database)
|
||||
{
|
||||
$container_name = generate_container_name($database->uuid);
|
||||
$destination = $database->destination;
|
||||
$image = $database->image;
|
||||
$docker_compose = [
|
||||
'version' => '3.8',
|
||||
'services' => [
|
||||
$container_name => [
|
||||
'image' => $image,
|
||||
'container_name' => $container_name,
|
||||
'environment'=> [
|
||||
'POSTGRES_USER' => $database->postgres_user,
|
||||
'POSTGRES_PASSWORD' => $database->postgres_password,
|
||||
'POSTGRES_DB' => $database->postgres_db,
|
||||
],
|
||||
'restart' => 'always',
|
||||
'networks' => [
|
||||
$destination->network,
|
||||
],
|
||||
'healthcheck' => [
|
||||
'test' => [
|
||||
'CMD-SHELL',
|
||||
'pg_isready',
|
||||
'-d',
|
||||
$database->postgres_db,
|
||||
],
|
||||
'interval' => '5s',
|
||||
'timeout' => '5s',
|
||||
'retries' => 10,
|
||||
'start_period' => '5s'
|
||||
],
|
||||
'mem_limit' => $database->limits_memory,
|
||||
'memswap_limit' => $database->limits_memory_swap,
|
||||
'mem_swappiness' => $database->limits_memory_swappiness,
|
||||
'mem_reservation' => $database->limits_memory_reservation,
|
||||
'cpus' => $database->limits_cpus,
|
||||
'cpuset' => $database->limits_cpuset,
|
||||
'cpu_shares' => $database->limits_cpu_shares,
|
||||
]
|
||||
],
|
||||
'networks' => [
|
||||
$destination->network => [
|
||||
'external' => false,
|
||||
'name' => $destination->network,
|
||||
'attachable' => true,
|
||||
]
|
||||
]
|
||||
];
|
||||
$docker_compose = Yaml::dump($docker_compose, 10);
|
||||
$docker_compose_base64 = base64_encode($docker_compose);
|
||||
$activity = remote_process([
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"sleep 4",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"echo 'Creating required Docker networks...'",
|
||||
"mkdir -p /tmp/{$container_name}",
|
||||
"echo '{$docker_compose_base64}' | base64 -d > /tmp/{$container_name}/docker-compose.yml",
|
||||
"docker compose -f /tmp/{$container_name}/docker-compose.yml up -d",
|
||||
|
||||
], $server);
|
||||
return $activity;
|
||||
|
@ -25,6 +25,7 @@ public function configuration()
|
||||
if (!$application) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
ray($application->persistentStorages()->get());
|
||||
return view('project.application.configuration', ['application' => $application]);
|
||||
}
|
||||
public function deployments()
|
||||
|
@ -25,6 +25,7 @@ public function configuration()
|
||||
if (!$database) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
ray($database->persistentStorages()->get());
|
||||
return view('project.database.configuration', ['database' => $database]);
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ public function polling()
|
||||
$this->setStatus(ProcessStatus::ERROR);
|
||||
}
|
||||
$this->isPollingActive = false;
|
||||
$this->emit('activityFinished');
|
||||
}
|
||||
}
|
||||
protected function setStatus($status)
|
||||
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\EnvironmentVariable;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\EnvironmentVariable;
|
||||
use Livewire\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class All extends Component
|
||||
{
|
||||
public Application $application;
|
||||
public string|null $modalId = null;
|
||||
protected $listeners = ['refreshEnvs', 'submit'];
|
||||
public function mount()
|
||||
{
|
||||
$this->modalId = new Cuid2(7);
|
||||
}
|
||||
public function refreshEnvs()
|
||||
{
|
||||
$this->application->refresh();
|
||||
}
|
||||
public function submit($data)
|
||||
{
|
||||
try {
|
||||
$found = $this->application->environment_variables()->where('key', $data['key'])->first();
|
||||
if ($found) {
|
||||
$this->emit('error', 'Environment variable already exists.');
|
||||
return;
|
||||
}
|
||||
EnvironmentVariable::create([
|
||||
'key' => $data['key'],
|
||||
'value' => $data['value'],
|
||||
'is_build_time' => $data['is_build_time'],
|
||||
'is_preview' => $data['is_preview'],
|
||||
'application_id' => $this->application->id,
|
||||
]);
|
||||
$this->application->refresh();
|
||||
|
||||
$this->emit('success', 'Environment variable added successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler(err: $e, that: $this);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
|
||||
use App\Jobs\ApplicationContainerStatusJob;
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Models\Application;
|
||||
use App\Notifications\Application\StatusChanged;
|
||||
use Livewire\Component;
|
||||
@ -22,8 +22,8 @@ public function mount()
|
||||
|
||||
public function check_status()
|
||||
{
|
||||
dispatch_sync(new ApplicationContainerStatusJob(
|
||||
application: $this->application,
|
||||
dispatch_sync(new ContainerStatusJob(
|
||||
resource: $this->application,
|
||||
container_name: generate_container_name($this->application->uuid),
|
||||
));
|
||||
$this->application->refresh();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
|
||||
use App\Jobs\ApplicationContainerStatusJob;
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationPreview;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -24,8 +24,8 @@ public function mount()
|
||||
}
|
||||
public function loadStatus($pull_request_id)
|
||||
{
|
||||
dispatch(new ApplicationContainerStatusJob(
|
||||
application: $this->application,
|
||||
dispatch(new ContainerStatusJob(
|
||||
resource: $this->application,
|
||||
container_name: generate_container_name($this->application->uuid, $pull_request_id),
|
||||
pull_request_id: $pull_request_id
|
||||
));
|
||||
|
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
|
||||
use App\Models\Application;
|
||||
use Livewire\Component;
|
||||
|
||||
class ResourceLimits extends Component
|
||||
{
|
||||
public Application $application;
|
||||
protected $rules = [
|
||||
'application.limits_memory' => 'required|string',
|
||||
'application.limits_memory_swap' => 'required|string',
|
||||
'application.limits_memory_swappiness' => 'required|integer|min:0|max:100',
|
||||
'application.limits_memory_reservation' => 'required|string',
|
||||
'application.limits_cpus' => 'nullable',
|
||||
'application.limits_cpuset' => 'nullable',
|
||||
'application.limits_cpu_shares' => 'nullable',
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'application.limits_memory' => 'memory',
|
||||
'application.limits_memory_swap' => 'swap',
|
||||
'application.limits_memory_swappiness' => 'swappiness',
|
||||
'application.limits_memory_reservation' => 'reservation',
|
||||
'application.limits_cpus' => 'cpus',
|
||||
'application.limits_cpuset' => 'cpuset',
|
||||
'application.limits_cpu_shares' => 'cpu shares',
|
||||
];
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
if (!$this->application->limits_memory) {
|
||||
$this->application->limits_memory = "0";
|
||||
}
|
||||
if (!$this->application->limits_memory_swap) {
|
||||
$this->application->limits_memory_swap = "0";
|
||||
}
|
||||
if (!$this->application->limits_memory_swappiness) {
|
||||
$this->application->limits_memory_swappiness = "60";
|
||||
}
|
||||
if (!$this->application->limits_memory_reservation) {
|
||||
$this->application->limits_memory_reservation = "0";
|
||||
}
|
||||
if (!$this->application->limits_cpus) {
|
||||
$this->application->limits_cpus = "0";
|
||||
}
|
||||
if (!$this->application->limits_cpuset) {
|
||||
$this->application->limits_cpuset = "0";
|
||||
}
|
||||
if (!$this->application->limits_cpu_shares) {
|
||||
$this->application->limits_cpu_shares = 1024;
|
||||
}
|
||||
$this->validate();
|
||||
$this->application->save();
|
||||
$this->emit('success', 'Resource limits updated successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler(err: $e, that: $this);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,18 +4,45 @@
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Actions\Database\StartPostgresql;
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Notifications\Application\StatusChanged;
|
||||
|
||||
class Heading extends Component
|
||||
{
|
||||
public $database;
|
||||
public array $parameters;
|
||||
|
||||
protected $listeners = ['activityFinished'];
|
||||
public function activityFinished() {
|
||||
$this->database->update([
|
||||
'started_at' => now(),
|
||||
]);
|
||||
$this->emit('refresh');
|
||||
$this->check_status();
|
||||
}
|
||||
public function check_status()
|
||||
{
|
||||
dispatch_sync(new ContainerStatusJob(
|
||||
resource: $this->database,
|
||||
container_name: generate_container_name($this->database->uuid),
|
||||
));
|
||||
$this->database->refresh();
|
||||
}
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = getRouteParameters();
|
||||
}
|
||||
public function stop() {
|
||||
remote_process(
|
||||
["docker rm -f {$this->database->uuid}"],
|
||||
$this->database->destination->server
|
||||
);
|
||||
$this->database->status = 'stopped';
|
||||
$this->database->save();
|
||||
$this->database->environment->project->team->notify(new StatusChanged($this->database));
|
||||
}
|
||||
public function start() {
|
||||
if ($this->database->type() === 'postgresql') {
|
||||
if ($this->database->type() === 'standalone-postgresql') {
|
||||
$activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database);
|
||||
$this->emit('newMonitorActivity', $activity->id);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
class General extends Component
|
||||
{
|
||||
public $database;
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
protected $rules = [
|
||||
'database.name' => 'required',
|
||||
'database.description' => 'nullable',
|
||||
@ -16,6 +18,7 @@ class General extends Component
|
||||
'database.postgres_initdb_args' => 'nullable',
|
||||
'database.postgres_host_auth_method' => 'nullable',
|
||||
'database.init_scripts' => 'nullable',
|
||||
'database.image' => 'required',
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'database.name' => 'Name',
|
||||
@ -26,7 +29,11 @@ class General extends Component
|
||||
'database.postgres_initdb_args' => 'Postgres Initdb Args',
|
||||
'database.postgres_host_auth_method' => 'Postgres Host Auth Method',
|
||||
'database.init_scripts' => 'Init Scripts',
|
||||
'database.image' => 'Image',
|
||||
];
|
||||
public function refresh() {
|
||||
$this->database->refresh();
|
||||
}
|
||||
public function submit() {
|
||||
try {
|
||||
$this->validate();
|
||||
|
@ -1,14 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
namespace App\Http\Livewire\Project\Shared;
|
||||
|
||||
use App\Models\Application;
|
||||
use Livewire\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class Danger extends Component
|
||||
{
|
||||
public Application $application;
|
||||
public $resource;
|
||||
public array $parameters;
|
||||
public string|null $modalId = null;
|
||||
|
||||
@ -19,10 +18,10 @@ public function mount()
|
||||
}
|
||||
public function delete()
|
||||
{
|
||||
$destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
|
||||
$destination = $this->resource->destination->getMorphClass()::where('id', $this->resource->destination->id)->first();
|
||||
|
||||
instant_remote_process(["docker rm -f {$this->application->uuid}"], $destination->server);
|
||||
$this->application->delete();
|
||||
instant_remote_process(["docker rm -f {$this->resource->uuid}"], $destination->server);
|
||||
$this->resource->delete();
|
||||
return redirect()->route('project.resources', [
|
||||
'project_uuid' => $this->parameters['project_uuid'],
|
||||
'environment_name' => $this->parameters['environment_name']
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application;
|
||||
namespace App\Http\Livewire\Project\Shared;
|
||||
|
||||
use Livewire\Component;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\EnvironmentVariable;
|
||||
namespace App\Http\Livewire\Project\Shared\EnvironmentVariable;
|
||||
|
||||
use Livewire\Component;
|
||||
|
49
app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php
Normal file
49
app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Shared\EnvironmentVariable;
|
||||
|
||||
use App\Models\EnvironmentVariable;
|
||||
use Livewire\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class All extends Component
|
||||
{
|
||||
public $resource;
|
||||
public string|null $modalId = null;
|
||||
protected $listeners = ['refreshEnvs', 'submit'];
|
||||
public function mount()
|
||||
{
|
||||
$this->modalId = new Cuid2(7);
|
||||
}
|
||||
public function refreshEnvs()
|
||||
{
|
||||
$this->resource->refresh();
|
||||
}
|
||||
public function submit($data)
|
||||
{
|
||||
try {
|
||||
$found = $this->resource->environment_variables()->where('key', $data['key'])->first();
|
||||
if ($found) {
|
||||
$this->emit('error', 'Environment variable already exists.');
|
||||
return;
|
||||
}
|
||||
$environment = new EnvironmentVariable();
|
||||
$environment->key = $data['key'];
|
||||
$environment->value = $data['value'];
|
||||
$environment->is_build_time = $data['is_build_time'];
|
||||
$environment->is_preview = $data['is_preview'];
|
||||
|
||||
if($this->resource->type() === 'application') {
|
||||
$environment->application_id = $this->resource->id;
|
||||
}
|
||||
if($this->resource->type() === 'standalone-postgresql') {
|
||||
$environment->standalone_postgresql_id = $this->resource->id;
|
||||
}
|
||||
$environment->save();
|
||||
$this->resource->refresh();
|
||||
$this->emit('success', 'Environment variable added successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler(err: $e, that: $this);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\EnvironmentVariable;
|
||||
namespace App\Http\Livewire\Project\Shared\EnvironmentVariable;
|
||||
|
||||
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
|
||||
use Livewire\Component;
|
59
app/Http/Livewire/Project/Shared/ResourceLimits.php
Normal file
59
app/Http/Livewire/Project/Shared/ResourceLimits.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Shared;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class ResourceLimits extends Component
|
||||
{
|
||||
public $resource;
|
||||
protected $rules = [
|
||||
'resource.limits_memory' => 'required|string',
|
||||
'resource.limits_memory_swap' => 'required|string',
|
||||
'resource.limits_memory_swappiness' => 'required|integer|min:0|max:100',
|
||||
'resource.limits_memory_reservation' => 'required|string',
|
||||
'resource.limits_cpus' => 'nullable',
|
||||
'resource.limits_cpuset' => 'nullable',
|
||||
'resource.limits_cpu_shares' => 'nullable',
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'resource.limits_memory' => 'memory',
|
||||
'resource.limits_memory_swap' => 'swap',
|
||||
'resource.limits_memory_swappiness' => 'swappiness',
|
||||
'resource.limits_memory_reservation' => 'reservation',
|
||||
'resource.limits_cpus' => 'cpus',
|
||||
'resource.limits_cpuset' => 'cpuset',
|
||||
'resource.limits_cpu_shares' => 'cpu shares',
|
||||
];
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
if (!$this->resource->limits_memory) {
|
||||
$this->resource->limits_memory = "0";
|
||||
}
|
||||
if (!$this->resource->limits_memory_swap) {
|
||||
$this->resource->limits_memory_swap = "0";
|
||||
}
|
||||
if (!$this->resource->limits_memory_swappiness) {
|
||||
$this->resource->limits_memory_swappiness = "60";
|
||||
}
|
||||
if (!$this->resource->limits_memory_reservation) {
|
||||
$this->resource->limits_memory_reservation = "0";
|
||||
}
|
||||
if (!$this->resource->limits_cpus) {
|
||||
$this->resource->limits_cpus = "0";
|
||||
}
|
||||
if (!$this->resource->limits_cpuset) {
|
||||
$this->resource->limits_cpuset = "0";
|
||||
}
|
||||
if (!$this->resource->limits_cpu_shares) {
|
||||
$this->resource->limits_cpu_shares = 1024;
|
||||
}
|
||||
$this->validate();
|
||||
$this->resource->save();
|
||||
$this->emit('success', 'Resource limits updated successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler(err: $e, that: $this);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\Storages;
|
||||
namespace App\Http\Livewire\Project\Shared\Storages;
|
||||
|
||||
use Livewire\Component;
|
||||
|
@ -1,18 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\Storages;
|
||||
namespace App\Http\Livewire\Project\Shared\Storages;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\LocalPersistentVolume;
|
||||
use Livewire\Component;
|
||||
|
||||
class All extends Component
|
||||
{
|
||||
public Application $application;
|
||||
public $resource;
|
||||
protected $listeners = ['refreshStorages', 'submit'];
|
||||
public function refreshStorages()
|
||||
{
|
||||
$this->application->refresh();
|
||||
$this->resource->refresh();
|
||||
}
|
||||
public function submit($data)
|
||||
{
|
||||
@ -21,10 +20,10 @@ public function submit($data)
|
||||
'name' => $data['name'],
|
||||
'mount_path' => $data['mount_path'],
|
||||
'host_path' => $data['host_path'],
|
||||
'resource_id' => $this->application->id,
|
||||
'resource_type' => Application::class,
|
||||
'resource_id' => $this->resource->id,
|
||||
'resource_type' => $this->resource->getMorphClass(),
|
||||
]);
|
||||
$this->application->refresh();
|
||||
$this->resource->refresh();
|
||||
$this->emit('success', 'Storage added successfully');
|
||||
$this->emit('clearAddStorage');
|
||||
} catch (\Exception $e) {
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\Application\Storages;
|
||||
namespace App\Http\Livewire\Project\Shared\Storages;
|
||||
|
||||
use Livewire\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
@ -13,17 +13,17 @@
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ApplicationContainerStatusJob implements ShouldQueue, ShouldBeUnique
|
||||
class ContainerStatusJob implements ShouldQueue, ShouldBeUnique
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public string $container_name;
|
||||
public string|null $pull_request_id;
|
||||
public Application $application;
|
||||
public $resource;
|
||||
|
||||
public function __construct($application, string $container_name, string|null $pull_request_id = null)
|
||||
public function __construct($resource, string $container_name, string|null $pull_request_id = null)
|
||||
{
|
||||
$this->application = $application;
|
||||
$this->resource = $resource;
|
||||
$this->container_name = $container_name;
|
||||
$this->pull_request_id = $pull_request_id;
|
||||
}
|
||||
@ -34,18 +34,18 @@ public function uniqueId(): string
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
$status = get_container_status(server: $this->application->destination->server, container_id: $this->container_name, throwError: false);
|
||||
if ($this->application->status === 'running' && $status === 'stopped') {
|
||||
$this->application->environment->project->team->notify(new StatusChanged($this->application));
|
||||
$status = get_container_status(server: $this->resource->destination->server, container_id: $this->container_name, throwError: false);
|
||||
if ($this->resource->status === 'running' && $status === 'stopped') {
|
||||
$this->resource->environment->project->team->notify(new StatusChanged($this->resource));
|
||||
}
|
||||
|
||||
if ($this->pull_request_id) {
|
||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id);
|
||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->resource->id, $this->pull_request_id);
|
||||
$preview->status = $status;
|
||||
$preview->save();
|
||||
} else {
|
||||
$this->application->status = $status;
|
||||
$this->application->save();
|
||||
$this->resource->status = $status;
|
||||
$this->resource->save();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
ray($e->getMessage());
|
@ -23,8 +23,8 @@ public function handle(): void
|
||||
{
|
||||
try {
|
||||
foreach ($this->applications as $application) {
|
||||
dispatch(new ApplicationContainerStatusJob(
|
||||
application: $application,
|
||||
dispatch(new ContainerStatusJob(
|
||||
resource: $application,
|
||||
container_name: generate_container_name($application->uuid),
|
||||
));
|
||||
}
|
||||
|
@ -43,7 +43,9 @@ protected static function booted()
|
||||
'publish_directory',
|
||||
'private_key_id'
|
||||
];
|
||||
|
||||
public function type() {
|
||||
return 'application';
|
||||
}
|
||||
public function publishDirectory(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
@ -33,7 +33,7 @@ public function applications()
|
||||
}
|
||||
public function postgresqls()
|
||||
{
|
||||
return $this->hasMany(StandalonePostgres::class);
|
||||
return $this->hasMany(StandalonePostgresql::class);
|
||||
}
|
||||
public function services()
|
||||
{
|
||||
|
@ -9,10 +9,16 @@
|
||||
|
||||
class EnvironmentVariable extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
"key" => 'string',
|
||||
'value' => 'encrypted',
|
||||
'is_build_time' => 'boolean',
|
||||
];
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($environment_variable) {
|
||||
if (!$environment_variable->is_preview) {
|
||||
if ($environment_variable->application_id && !$environment_variable->is_preview) {
|
||||
ModelsEnvironmentVariable::create([
|
||||
'key' => $environment_variable->key,
|
||||
'value' => $environment_variable->value,
|
||||
@ -23,12 +29,7 @@ protected static function booted()
|
||||
}
|
||||
});
|
||||
}
|
||||
protected $fillable = ['key', 'value', 'is_build_time', 'application_id', 'is_preview'];
|
||||
protected $casts = [
|
||||
"key" => 'string',
|
||||
'value' => 'encrypted',
|
||||
'is_build_time' => 'boolean',
|
||||
];
|
||||
|
||||
private function get_environment_variables(string $environment_variable): string|null
|
||||
{
|
||||
// $team_id = session('currentTeam')->id;
|
||||
|
@ -8,18 +8,15 @@
|
||||
|
||||
class LocalPersistentVolume extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'mount_path',
|
||||
'host_path',
|
||||
'container_id',
|
||||
'resource_id',
|
||||
'resource_type',
|
||||
];
|
||||
protected $guarded = [];
|
||||
public function application()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
public function standalone_postgresql()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
protected function name(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
@ -48,6 +48,6 @@ public function applications()
|
||||
}
|
||||
public function postgresqls()
|
||||
{
|
||||
return $this->hasManyThrough(StandalonePostgres::class, Environment::class);
|
||||
return $this->hasManyThrough(StandalonePostgresql::class, Environment::class);
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ public function applications()
|
||||
}
|
||||
public function postgresqls()
|
||||
{
|
||||
return $this->morphMany(StandalonePostgres::class, 'destination');
|
||||
return $this->morphMany(StandalonePostgresql::class, 'destination');
|
||||
}
|
||||
public function server()
|
||||
{
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class StandalonePostgres extends BaseModel
|
||||
{
|
||||
use HasFactory;
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'postgres_password' => 'encrypted',
|
||||
];
|
||||
public function type() {
|
||||
return 'postgresql';
|
||||
}
|
||||
public function environment()
|
||||
{
|
||||
return $this->belongsTo(Environment::class);
|
||||
}
|
||||
public function destination()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
50
app/Models/StandalonePostgresql.php
Normal file
50
app/Models/StandalonePostgresql.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use App\Models\EnvironmentVariable;
|
||||
use App\Models\LocalPersistentVolume;
|
||||
|
||||
class StandalonePostgresql extends BaseModel
|
||||
{
|
||||
use HasFactory;
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($database) {
|
||||
LocalPersistentVolume::create([
|
||||
'name' => 'postgres-data-' . $database->uuid,
|
||||
'mount_path' => '/var/lib/postgresql/data',
|
||||
'host_path' => null,
|
||||
'resource_id' => $database->id,
|
||||
'resource_type' => $database->getMorphClass(),
|
||||
'is_readonly' => true
|
||||
]);
|
||||
});
|
||||
}
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'postgres_password' => 'encrypted',
|
||||
];
|
||||
public function type() {
|
||||
return 'standalone-postgresql';
|
||||
}
|
||||
public function environment()
|
||||
{
|
||||
return $this->belongsTo(Environment::class);
|
||||
}
|
||||
public function destination()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
public function environment_variables(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class);
|
||||
}
|
||||
|
||||
public function persistentStorages()
|
||||
{
|
||||
return $this->morphMany(LocalPersistentVolume::class, 'resource');
|
||||
}
|
||||
}
|
@ -15,21 +15,21 @@
|
||||
class StatusChanged extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
public Application $application;
|
||||
public $application;
|
||||
|
||||
public string $application_name;
|
||||
public string|null $application_url = null;
|
||||
public string $project_uuid;
|
||||
public string $environment_name;
|
||||
public string $fqdn;
|
||||
public string|null $fqdn;
|
||||
|
||||
public function __construct(Application $application)
|
||||
public function __construct($application)
|
||||
{
|
||||
$this->application = $application;
|
||||
$this->application_name = data_get($application, 'name');
|
||||
$this->project_uuid = data_get($application, 'environment.project.uuid');
|
||||
$this->environment_name = data_get($application, 'environment.name');
|
||||
$this->fqdn = data_get($application, 'fqdn');
|
||||
$this->fqdn = data_get($application, 'fqdn', null);
|
||||
if (Str::of($this->fqdn)->explode(',')->count() > 1) {
|
||||
$this->fqdn = Str::of($this->fqdn)->explode(',')->first();
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('standalone_postgres', function (Blueprint $table) {
|
||||
Schema::create('standalone_postgresqls', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->string('name');
|
||||
@ -24,9 +24,21 @@ public function up(): void
|
||||
$table->string('postgres_host_auth_method')->nullable();
|
||||
$table->json('init_scripts')->nullable();
|
||||
|
||||
$table->string('status')->default('exited');
|
||||
|
||||
$table->string('image')->default('postgres:15-alpine');
|
||||
$table->boolean('is_public')->default(false);
|
||||
$table->integer('public_port')->nullable();
|
||||
|
||||
$table->string('limits_memory')->default("0");
|
||||
$table->string('limits_memory_swap')->default("0");
|
||||
$table->integer('limits_memory_swappiness')->default(60);
|
||||
$table->string('limits_memory_reservation')->default("0");
|
||||
|
||||
$table->string('limits_cpus')->default("0");
|
||||
$table->string('limits_cpuset')->nullable()->default("0");
|
||||
$table->integer('limits_cpu_shares')->default(1024);
|
||||
|
||||
$table->timestamp('started_at')->nullable();
|
||||
$table->morphs('destination');
|
||||
|
||||
@ -40,6 +52,6 @@ public function up(): void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('standalone_postgres');
|
||||
Schema::dropIfExists('standalone_postgresqls');
|
||||
}
|
||||
};
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('environment_variables', function (Blueprint $table) {
|
||||
$table->dropColumn('service_id');
|
||||
$table->dropColumn('database_id');
|
||||
$table->foreignId('standalone_postgresql_id')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('environment_variables', function (Blueprint $table) {
|
||||
$table->foreignId('service_id')->nullable();
|
||||
$table->foreignId('database_id')->nullable();
|
||||
$table->dropColumn('standalone_postgresql_id');
|
||||
});
|
||||
}
|
||||
};
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('local_persistent_volumes', function (Blueprint $table) {
|
||||
$table->boolean('is_readonly')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('local_persistent_volumes', function (Blueprint $table) {
|
||||
$table->dropColumn('is_readonly');
|
||||
});
|
||||
}
|
||||
};
|
@ -32,7 +32,7 @@ public function run(): void
|
||||
EnvironmentVariableSeeder::class,
|
||||
LocalPersistentVolumeSeeder::class,
|
||||
S3StorageSeeder::class,
|
||||
StandalonePostgresSeeder::class,
|
||||
StandalonePostgresqlSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
@ -4,17 +4,17 @@
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\StandalonePostgres;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use App\Models\StandaloneDocker;
|
||||
|
||||
class StandalonePostgresSeeder extends Seeder
|
||||
class StandalonePostgresqlSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
StandalonePostgres::create([
|
||||
StandalonePostgresql::create([
|
||||
'name' => 'Local PostgreSQL',
|
||||
'description' => 'Local PostgreSQL for testing',
|
||||
'postgres_password' => 'postgres',
|
@ -8,17 +8,6 @@
|
||||
{{-- <x-applications.advanced :application="$application" /> --}}
|
||||
|
||||
@if ($database->status === 'running')
|
||||
<button wire:click='start' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-warning" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path
|
||||
d="M10.09 4.01l.496 -.495a2 2 0 0 1 2.828 0l7.071 7.07a2 2 0 0 1 0 2.83l-7.07 7.07a2 2 0 0 1 -2.83 0l-7.07 -7.07a2 2 0 0 1 0 -2.83l3.535 -3.535h-3.988">
|
||||
</path>
|
||||
<path d="M7.05 11.038v-3.988"></path>
|
||||
</svg>
|
||||
Restart
|
||||
</button>
|
||||
<button wire:click='stop' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
|
@ -1,26 +0,0 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Environment Variables</h2>
|
||||
<x-forms.button class="btn" onclick="newVariable.showModal()">+ Add</x-forms.button>
|
||||
<livewire:project.application.environment-variable.add />
|
||||
</div>
|
||||
<div class="">Environment (secrets) variables for normal deployments.</div>
|
||||
</div>
|
||||
@forelse ($application->environment_variables as $env)
|
||||
<livewire:project.application.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" />
|
||||
@empty
|
||||
<div class="text-neutral-500">No environment variables found.</div>
|
||||
@endforelse
|
||||
@if ($application->environment_variables_preview->count() > 0)
|
||||
<div>
|
||||
<h3>Preview Deployments</h3>
|
||||
<div class="">Environment (secrets) variables for Preview Deployments.</div>
|
||||
</div>
|
||||
@foreach ($application->environment_variables_preview as $env)
|
||||
<livewire:project.application.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" />
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
@ -1,21 +0,0 @@
|
||||
<div>
|
||||
<x-modal yesOrNo modalId="{{ $modalId }}" modalTitle="Delete Storage">
|
||||
<x-slot:modalBody>
|
||||
<p>This storage will be deleted <span class="font-bold text-warning">({{ $storage->name }})</span>. It is not
|
||||
reversible. <br>Please think again.</p>
|
||||
</x-slot:modalBody>
|
||||
</x-modal>
|
||||
<form wire:submit.prevent='submit' class="flex flex-col gap-2 xl:items-end xl:flex-row">
|
||||
<x-forms.input id="storage.name" label="Name" required />
|
||||
<x-forms.input id="storage.host_path" label="Source Path" />
|
||||
<x-forms.input id="storage.mount_path" label="Destination Path" required />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit">
|
||||
Update
|
||||
</x-forms.button>
|
||||
<x-forms.button isError isModal modalId="{{ $modalId }}">
|
||||
Delete
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -1,4 +1,4 @@
|
||||
<nav>
|
||||
<nav x-init="$wire.check_status" wire:poll.10000ms="check_status">
|
||||
<x-resources.breadcrumbs :resource="$database" :parameters="$parameters" />
|
||||
<x-databases.navbar :database="$database" :parameters="$parameters" />
|
||||
</nav>
|
||||
|
@ -1,17 +1,33 @@
|
||||
<div>
|
||||
<form wire:submit.prevent="submit">
|
||||
<form wire:submit.prevent="submit" class="flex flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>General</h2>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input label="Name" id="database.name" />
|
||||
<x-forms.input label="Description" id="database.description" />
|
||||
<x-forms.input label="Image" id="database.image" required
|
||||
helper="For all available images, check here:<br><br><a target='_blank' href='https://hub.docker.com/_/postgres'>https://hub.docker.com/_/postgres</a>" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@if ($database->started_at)
|
||||
<x-forms.input label="Username" id="database.postgres_username" placeholder="If empty, use postgres."
|
||||
readonly />
|
||||
<x-forms.input label="Password" id="database.postgres_password" type="password" required readonly />
|
||||
<x-forms.input label="Database" id="database.postgres_db" placeholder="If empty, use $USERNAME."
|
||||
readonly />
|
||||
@else
|
||||
<x-forms.input label="Username" id="database.postgres_username" placeholder="If empty, use postgres." />
|
||||
<x-forms.input label="Password" id="database.postgres_password" type="password" />
|
||||
<x-forms.input label="Password" id="database.postgres_password" type="password" required />
|
||||
<x-forms.input label="Database" id="database.postgres_db" placeholder="If empty, use $USERNAME." />
|
||||
<x-forms.input label="Init Args" id="database.postgres_initdb_args" placeholder="If empty, use default." />
|
||||
@endif
|
||||
|
||||
</div>
|
||||
<x-forms.input label="Initial Arguments" id="database.postgres_initdb_args"
|
||||
placeholder="If empty, use default." />
|
||||
<x-forms.input label="Host Auth Method" id="database.postgres_host_auth_method"
|
||||
placeholder="If empty, use default." />
|
||||
</form>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<div>
|
||||
<x-modal yesOrNo modalId="{{ $modalId }}" modalTitle="Delete Application">
|
||||
<x-modal yesOrNo modalId="{{ $modalId }}" modalTitle="Delete Resource">
|
||||
<x-slot:modalBody>
|
||||
<p>This application will be deleted. It is not reversible. <br>Please think again.</p>
|
||||
<p>This resource will be deleted. It is not reversible. <br>Please think again.</p>
|
||||
</x-slot:modalBody>
|
||||
</x-modal>
|
||||
<h3>Danger Zone</h3>
|
||||
<div class="">Woah. I hope you know what are you doing.</div>
|
||||
<h4 class="pt-4">Delete Application</h4>
|
||||
<h4 class="pt-4">Delete Resource</h4>
|
||||
<div class="pb-4">This will stop your containers, delete all related data, etc. Beware! There is no coming
|
||||
back!
|
||||
</div>
|
@ -0,0 +1,8 @@
|
||||
<div>
|
||||
<h2>Destination</h2>
|
||||
<div class="">The destination server / network where your application will be deployed to.</div>
|
||||
<div class="py-4 ">
|
||||
<p>Server: {{ data_get($destination, 'server.name') }}</p>
|
||||
<p>Destination Network: {{ $destination->network }}</p>
|
||||
</div>
|
||||
</div>
|
@ -3,7 +3,9 @@
|
||||
<h3 class="text-lg font-bold">Add Environment Variable</h3>
|
||||
<x-forms.input placeholder="NODE_ENV" id="key" label="Name" required />
|
||||
<x-forms.input placeholder="production" id="value" label="Value" required />
|
||||
@if (data_get($parameters, 'application_uuid'))
|
||||
<x-forms.checkbox id="is_build_time" label="Build Variable?" />
|
||||
@endif
|
||||
<x-forms.button onclick="newVariable.close()" type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
@ -0,0 +1,26 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Environment Variables</h2>
|
||||
<x-forms.button class="btn" onclick="newVariable.showModal()">+ Add</x-forms.button>
|
||||
<livewire:project.shared.environment-variable.add />
|
||||
</div>
|
||||
<div>Environment (secrets) variables for this resource.</div>
|
||||
</div>
|
||||
@forelse ($resource->environment_variables as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" />
|
||||
@empty
|
||||
<div class="text-neutral-500">No environment variables found.</div>
|
||||
@endforelse
|
||||
@if ($resource->type() === 'application' && $resource->environment_variables_preview->count() > 0)
|
||||
<div>
|
||||
<h3>Preview Deployments</h3>
|
||||
<div>Environment (secrets) variables for Preview Deployments.</div>
|
||||
</div>
|
||||
@foreach ($resource->environment_variables_preview as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" />
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
@ -8,7 +8,9 @@ class="font-bold text-warning">({{ $env->key }})</span>?</p>
|
||||
<form wire:submit.prevent='submit' class="flex flex-col items-center gap-2 xl:flex-row">
|
||||
<x-forms.input id="env.key" />
|
||||
<x-forms.input type="password" id="env.value" />
|
||||
@if (data_get($parameters, 'application_uuid'))
|
||||
<x-forms.checkbox disabled id="env.is_build_time" label="Build Variable?" />
|
||||
@endif
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit">
|
||||
Update
|
@ -7,20 +7,20 @@
|
||||
<div class="">Limit your container resources by CPU & memory.</div>
|
||||
<h3 class="pt-4">Limit CPUs</h3>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="1.5" label="Number of CPUs" id="application.limits_cpus" />
|
||||
<x-forms.input placeholder="0-2" label="CPU sets to use" id="application.limits_cpuset" />
|
||||
<x-forms.input placeholder="1024" label="CPU Weight" id="application.limits_cpu_shares" />
|
||||
<x-forms.input placeholder="1.5" label="Number of CPUs" id="resource.limits_cpus" />
|
||||
<x-forms.input placeholder="0-2" label="CPU sets to use" id="resource.limits_cpuset" />
|
||||
<x-forms.input placeholder="1024" label="CPU Weight" id="resource.limits_cpu_shares" />
|
||||
</div>
|
||||
<h3 class="pt-4">Limit Memory</h3>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="69b or 420k or 1337m or 1g" label="Soft Memory Limit"
|
||||
id="application.limits_memory_reservation" />
|
||||
id="resource.limits_memory_reservation" />
|
||||
<x-forms.input placeholder="69b or 420k or 1337m or 1g" label="Maximum Memory Limit"
|
||||
id="application.limits_memory" />
|
||||
id="resource.limits_memory" />
|
||||
<x-forms.input placeholder="69b or 420k or 1337m or 1g" label="Maximum Swap Limit"
|
||||
id="application.limits_memory_swap" />
|
||||
id="resource.limits_memory_swap" />
|
||||
<x-forms.input placeholder="0-100" type="number" min="0" max="100" label="Swappiness"
|
||||
id="application.limits_memory_swappiness" />
|
||||
id="resource.limits_memory_swappiness" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -7,13 +7,13 @@
|
||||
volume
|
||||
name, example: <span class='text-helper'>-pr-1</span>" />
|
||||
<x-forms.button class="btn" onclick="newStorage.showModal()">+ Add</x-forms.button>
|
||||
<livewire:project.application.storages.add />
|
||||
<livewire:project.shared.storages.add />
|
||||
</div>
|
||||
<div class="">Persistent storage to preserve data between deployments.</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
@forelse ($application->persistentStorages as $storage)
|
||||
<livewire:project.application.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage" />
|
||||
@forelse ($resource->persistentStorages as $storage)
|
||||
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage" />
|
||||
@empty
|
||||
<div class="text-neutral-500">No storages found.</div>
|
||||
@endforelse
|
@ -0,0 +1,35 @@
|
||||
<div>
|
||||
<x-modal yesOrNo modalId="{{ $modalId }}" modalTitle="Delete Storage">
|
||||
<x-slot:modalBody>
|
||||
<p>This storage will be deleted <span class="font-bold text-warning">({{ $storage->name }})</span>. It is not
|
||||
reversible. <br>Please think again.</p>
|
||||
</x-slot:modalBody>
|
||||
</x-modal>
|
||||
<form wire:submit.prevent='submit' class="flex flex-col gap-2 xl:items-end xl:flex-row">
|
||||
@if ($storage->is_readonly)
|
||||
<x-forms.input id="storage.name" label="Name" required readonly />
|
||||
<x-forms.input id="storage.host_path" label="Source Path" readonly />
|
||||
<x-forms.input id="storage.mount_path" label="Destination Path" required readonly />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit" disabled>
|
||||
Update
|
||||
</x-forms.button>
|
||||
<x-forms.button isError isModal modalId="{{ $modalId }}" disabled>
|
||||
Delete
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@else
|
||||
<x-forms.input id="storage.name" label="Name" required />
|
||||
<x-forms.input id="storage.host_path" label="Source Path" />
|
||||
<x-forms.input id="storage.mount_path" label="Destination Path" required />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit">
|
||||
Update
|
||||
</x-forms.button>
|
||||
<x-forms.button isError isModal modalId="{{ $modalId }}">
|
||||
Delete
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
@ -38,16 +38,16 @@
|
||||
<livewire:project.application.general :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||
<livewire:project.application.environment-variable.all :application="$application" />
|
||||
<livewire:project.shared.environment-variable.all :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'source'">
|
||||
<livewire:project.application.source :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'destination'">
|
||||
<livewire:project.application.destination :destination="$application->destination" />
|
||||
<livewire:project.shared.destination :destination="$application->destination" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'storages'">
|
||||
<livewire:project.application.storages.all :application="$application" />
|
||||
<livewire:project.shared.storages.all :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'previews'">
|
||||
<livewire:project.application.previews :application="$application" />
|
||||
@ -56,10 +56,10 @@
|
||||
<livewire:project.application.rollback :application="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-limits'">
|
||||
<livewire:project.application.resource-limits :application="$application" />
|
||||
<livewire:project.shared.resource-limits :resource="$application" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'danger'">
|
||||
<livewire:project.application.danger :application="$application" />
|
||||
<livewire:project.shared.danger :resource="$application" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,8 +19,6 @@
|
||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
||||
href="#">Environment
|
||||
Variables</a>
|
||||
<a :class="activeTab === 'source' && 'text-white'"
|
||||
@click.prevent="activeTab = 'source'; window.location.hash = 'source'" href="#">Source</a>
|
||||
<a :class="activeTab === 'destination' && 'text-white'"
|
||||
@click.prevent="activeTab = 'destination'; window.location.hash = 'destination'"
|
||||
href="#">Destination
|
||||
@ -38,27 +36,24 @@
|
||||
</div>
|
||||
<div class="w-full pl-8">
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
@if ($database->type() === 'postgresql')
|
||||
@if ($database->type() === 'standalone-postgresql')
|
||||
<livewire:project.database.postgresql.general :database="$database" />
|
||||
@endif
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||
{{-- <livewire:project.application.environment-variable.all :application="$application" /> --}}
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'source'">
|
||||
{{-- <livewire:project.application.source :application="$application" /> --}}
|
||||
<livewire:project.shared.environment-variable.all :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'destination'">
|
||||
{{-- <livewire:project.application.destination :destination="$application->destination" /> --}}
|
||||
<livewire:project.shared.destination :destination="$database->destination" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'storages'">
|
||||
{{-- <livewire:project.application.storages.all :application="$application" /> --}}
|
||||
<livewire:project.shared.storages.all :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'resource-limits'">
|
||||
{{-- <livewire:project.application.resource-limits :application="$application" /> --}}
|
||||
<livewire:project.shared.resource-limits :resource="$database" />
|
||||
</div>
|
||||
<div x-cloak x-show="activeTab === 'danger'">
|
||||
{{-- <livewire:project.application.danger :application="$application" /> --}}
|
||||
<livewire:project.shared.danger :resource="$database" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user