Merge branch 'next' into feat--terminal-pty

This commit is contained in:
Andras Bacsai
2024-09-11 10:41:33 +02:00
committed by GitHub
197 changed files with 8925 additions and 3563 deletions

View File

@@ -66,9 +66,9 @@ class Advanced extends Component
$this->dispatch('resetDefaultLabels', false);
}
if ($this->application->settings->is_raw_compose_deployment_enabled) {
$this->application->parseRawCompose();
$this->application->oldRawParser();
} else {
$this->application->parseCompose();
$this->application->parse();
}
$this->application->settings->save();
$this->dispatch('success', 'Settings saved.');

View File

@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Application\Deployment;
use App\Models\Application;
use App\Models\ApplicationDeploymentQueue;
use Illuminate\Support\Collection;
use Livewire\Component;
class Show extends Component
@@ -69,6 +70,20 @@ class Show extends Component
}
}
public function getLogLinesProperty()
{
return decode_remote_command_output($this->application_deployment_queue)->map(function ($logLine) {
$logLine['line'] = e($logLine['line']);
$logLine['line'] = preg_replace(
'/(https?:\/\/[^\s]+)/',
'<a href="$1" target="_blank" rel="noopener noreferrer" class="underline text-neutral-400">$1</a>',
$logLine['line'],
);
return $logLine;
});
}
public function render()
{
return view('livewire.project.application.deployment.show');

View File

@@ -131,7 +131,7 @@ class General extends Component
public function mount()
{
try {
$this->parsedServices = $this->application->parseCompose();
$this->parsedServices = $this->application->parse();
if (is_null($this->parsedServices) || empty($this->parsedServices)) {
$this->dispatch('error', 'Failed to parse your docker-compose file. Please check the syntax and try again.');
@@ -196,7 +196,7 @@ class General extends Component
// Must reload the application to get the latest database changes
// Why? Not sure, but it works.
$this->application->refresh();
// $this->application->refresh();
['parsedServices' => $this->parsedServices, 'initialDockerComposeLocation' => $this->initialDockerComposeLocation] = $this->application->loadComposeFile($isInit);
if (is_null($this->parsedServices)) {
@@ -204,7 +204,7 @@ class General extends Component
return;
}
$compose = $this->application->parseCompose();
$this->application->parse();
$this->dispatch('success', 'Docker compose file loaded.');
$this->dispatch('compose_loaded');
$this->dispatch('refreshStorages');

View File

@@ -79,8 +79,15 @@ class Previews extends Component
return;
}
$fqdn = generateFqdn($this->application->destination->server, $this->application->uuid);
if ($this->application->build_pack === 'dockercompose') {
$preview->generate_preview_fqdn_compose();
$this->application->refresh();
$this->dispatch('success', 'Domain generated.');
return;
}
$fqdn = generateFqdn($this->application->destination->server, $this->application->uuid);
$url = Url::fromString($fqdn);
$template = $this->application->preview_url_template;
$host = $url->getHost();

View File

@@ -8,9 +8,8 @@ use Livewire\Component;
class BackupExecutions extends Component
{
public ?ScheduledDatabaseBackup $backup = null;
public $database;
public $executions = [];
public $setDeletableBackup;
public function getListeners()
@@ -58,7 +57,53 @@ class BackupExecutions extends Component
public function refreshBackupExecutions(): void
{
if ($this->backup) {
$this->executions = $this->backup->executions()->get()->sortBy('created_at');
$this->executions = $this->backup->executions()->get();
}
}
public function mount(ScheduledDatabaseBackup $backup)
{
$this->backup = $backup;
$this->database = $backup->database;
$this->refreshBackupExecutions();
}
public function server()
{
if ($this->database) {
$server = null;
if ($this->database instanceof \App\Models\ServiceDatabase) {
$server = $this->database->service->destination->server;
} elseif ($this->database->destination && $this->database->destination->server) {
$server = $this->database->destination->server;
}
if ($server) {
return $server;
}
}
return null;
}
public function getServerTimezone()
{
$server = $this->server();
if (!$server) {
return 'UTC';
}
$serverTimezone = $server->settings->server_timezone;
return $serverTimezone;
}
public function formatDateInServerTimezone($date)
{
$serverTimezone = $this->getServerTimezone();
$dateObj = new \DateTime($date);
try {
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
} catch (\Exception $e) {
$dateObj->setTimezone(new \DateTimeZone('UTC'));
}
return $dateObj->format('Y-m-d H:i:s T');
}
}

View File

@@ -31,6 +31,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -42,6 +43,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Run Options',
];
public function mount()
@@ -54,7 +56,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -71,14 +73,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -93,7 +95,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -30,6 +30,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -40,6 +41,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Run Options',
];
public function mount()
@@ -52,7 +54,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -86,14 +88,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -108,7 +110,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -31,6 +31,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -42,6 +43,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Run Options',
];
public function mount()
@@ -55,7 +57,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -92,14 +94,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -114,7 +116,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -34,6 +34,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -48,6 +49,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Options',
];
public function mount()
@@ -61,7 +63,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -98,14 +100,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -120,7 +122,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -33,6 +33,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -46,6 +47,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Run Options',
];
public function mount()
@@ -59,7 +61,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -99,14 +101,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -121,7 +123,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -34,6 +34,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -48,6 +49,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Run Options',
];
public function mount()
@@ -60,7 +62,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -97,14 +99,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -119,7 +121,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -49,6 +49,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -65,6 +66,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Run Options',
];
public function mount()

View File

@@ -31,6 +31,7 @@ class General extends Component
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
'database.custom_docker_run_options' => 'nullable',
];
protected $validationAttributes = [
@@ -42,6 +43,7 @@ class General extends Component
'database.ports_mappings' => 'Port Mapping',
'database.is_public' => 'Is Public',
'database.public_port' => 'Public Port',
'database.custom_docker_run_options' => 'Custom Docker Options',
];
public function mount()
@@ -55,7 +57,7 @@ class General extends Component
public function instantSaveAdvanced()
{
try {
if (! $this->server->isLogDrainEnabled()) {
if (!$this->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
@@ -86,14 +88,14 @@ class General extends Component
public function instantSave()
{
try {
if ($this->database->is_public && ! $this->database->public_port) {
if ($this->database->is_public && !$this->database->public_port) {
$this->dispatch('error', 'Public port is required.');
$this->database->is_public = false;
return;
}
if ($this->database->is_public) {
if (! str($this->database->status)->startsWith('running')) {
if (!str($this->database->status)->startsWith('running')) {
$this->dispatch('error', 'Database must be started to be publicly accessible.');
$this->database->is_public = false;
@@ -108,7 +110,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->database->save();
} catch (\Throwable $e) {
$this->database->is_public = ! $this->database->is_public;
$this->database->is_public = !$this->database->is_public;
return handleError($e, $this);
}

View File

@@ -99,6 +99,16 @@ class PublicGitRepository extends Component
}
}
public function updatedDockerComposeLocation()
{
if ($this->docker_compose_location) {
$this->docker_compose_location = rtrim($this->docker_compose_location, '/');
if (! str($this->docker_compose_location)->startsWith('/')) {
$this->docker_compose_location = '/'.$this->docker_compose_location;
}
}
}
public function updatedBuildPack()
{
if ($this->build_pack === 'nixpacks') {

View File

@@ -45,6 +45,8 @@ class Select extends Component
public ?string $selectedEnvironment = null;
public string $postgresql_type = 'postgres:16-alpine';
public ?string $existingPostgresqlUrl = null;
public ?string $search = null;
@@ -202,6 +204,8 @@ class Select extends Component
$docker = $this->standaloneDockers->first() ?? $this->swarmDockers->first();
if ($docker) {
$this->setDestination($docker->uuid);
return $this->whatToDoNext();
}
}
$this->current_step = 'destinations';
@@ -211,15 +215,38 @@ class Select extends Component
{
$this->destination_uuid = $destination_uuid;
return $this->whatToDoNext();
}
public function setPostgresqlType(string $type)
{
$this->postgresql_type = $type;
return redirect()->route('project.resource.create', [
'project_uuid' => $this->parameters['project_uuid'],
'environment_name' => $this->parameters['environment_name'],
'type' => $this->type,
'destination' => $this->destination_uuid,
'server_id' => $this->server_id,
'database_image' => $this->postgresql_type,
]);
}
public function whatToDoNext()
{
if ($this->type === 'postgresql') {
$this->current_step = 'select-postgresql-type';
} else {
return redirect()->route('project.resource.create', [
'project_uuid' => $this->parameters['project_uuid'],
'environment_name' => $this->parameters['environment_name'],
'type' => $this->type,
'destination' => $this->destination_uuid,
'server_id' => $this->server_id,
]);
}
}
public function loadServers()
{
$this->servers = Server::isUsable()->get();

View File

@@ -18,6 +18,7 @@ class Create extends Component
$type = str(request()->query('type'));
$destination_uuid = request()->query('destination');
$server_id = request()->query('server_id');
$database_image = request()->query('database_image');
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
if (! $project) {
@@ -33,7 +34,11 @@ class Create extends Component
if (in_array($type, DATABASE_TYPES)) {
if ($type->value() === 'postgresql') {
$database = create_standalone_postgresql($environment->id, $destination_uuid);
$database = create_standalone_postgresql(
environmentId: $environment->id,
destinationUuid: $destination_uuid,
databaseImage: $database_image
);
} elseif ($type->value() === 'redis') {
$database = create_standalone_redis($environment->id, $destination_uuid);
} elseif ($type->value() === 'mongodb') {
@@ -86,18 +91,16 @@ class Create extends Component
$oneClickDotEnvs->each(function ($value) use ($service) {
$key = str()->before($value, '=');
$value = str(str()->after($value, '='));
$generatedValue = $value;
if ($value->contains('SERVICE_')) {
$command = $value->after('SERVICE_')->beforeLast('_');
$generatedValue = generateEnvValue($command->value(), $service);
if ($value) {
EnvironmentVariable::create([
'key' => $key,
'value' => $value,
'service_id' => $service->id,
'is_build_time' => false,
'is_preview' => false,
]);
}
EnvironmentVariable::create([
'key' => $key,
'value' => $generatedValue,
'service_id' => $service->id,
'is_build_time' => false,
'is_preview' => false,
]);
});
}
$service->parse(isNew: true);

View File

@@ -76,6 +76,12 @@ class Configuration extends Component
{
try {
GetContainersStatus::run($this->service->server);
$this->service->applications->each(function ($application) {
$application->refresh();
});
$this->service->databases->each(function ($database) {
$database->refresh();
});
$this->dispatch('$refresh');
} catch (\Exception $e) {
return handleError($e, $this);

View File

@@ -43,6 +43,7 @@ class EditCompose extends Component
{
$this->dispatch('info', 'Saving new docker compose...');
$this->dispatch('saveCompose', $this->service->docker_compose_raw);
$this->dispatch('refreshStorages');
}
public function instantSave()

View File

@@ -55,6 +55,7 @@ class FileStorage extends Component
$this->fileStorage->deleteStorageOnServer();
$this->fileStorage->is_directory = true;
$this->fileStorage->content = null;
$this->fileStorage->is_based_on_git = false;
$this->fileStorage->save();
$this->fileStorage->saveStorageOnServer();
} catch (\Throwable $e) {

View File

@@ -24,6 +24,7 @@ class All extends Component
protected $listeners = [
'saveKey' => 'submit',
'refreshEnvs',
'environmentVariableDeleted' => 'refreshEnvs',
];
@@ -52,11 +53,18 @@ class All extends Component
public function sortEnvironmentVariables()
{
$this->resource->load(['environment_variables', 'environment_variables_preview']);
if ($this->resource->type() === 'application') {
$this->resource->load(['environment_variables', 'environment_variables_preview']);
} else {
$this->resource->load(['environment_variables']);
}
$sortBy = data_get($this->resource, 'settings.is_env_sorting_enabled') ? 'key' : 'order';
$sortFunction = function ($variables) use ($sortBy) {
if (! $variables) {
return $variables;
}
if ($sortBy === 'key') {
return $variables->sortBy(function ($item) {
return strtolower($item->key);

View File

@@ -136,4 +136,4 @@ class Show extends Component
return handleError($e);
}
}
}
}

View File

@@ -97,7 +97,7 @@ class GetLogs extends Component
if (! $refresh && ($this->resource?->getMorphClass() === 'App\Models\Service' || str($this->container)->contains('-pr-'))) {
return;
}
if (! $this->numberOfLines) {
if ($this->numberOfLines <= 0) {
$this->numberOfLines = 1000;
}
if ($this->container) {

View File

@@ -26,7 +26,7 @@ class All extends Component
$this->containerNames = $this->containerNames->merge($this->resource->databases()->pluck('name'));
} elseif ($this->resource->type() == 'application') {
if ($this->resource->build_pack === 'dockercompose') {
$parsed = $this->resource->parseCompose();
$parsed = $this->resource->parse();
$containers = collect(data_get($parsed, 'services'))->keys();
$this->containerNames = $containers;
} else {

View File

@@ -7,8 +7,8 @@ use Livewire\Component;
class Executions extends Component
{
public $executions = [];
public $selectedKey;
public $task;
public function getListeners()
{
@@ -26,4 +26,44 @@ class Executions extends Component
}
$this->selectedKey = $key;
}
public function server()
{
if (!$this->task) {
return null;
}
if ($this->task->application) {
if ($this->task->application->destination && $this->task->application->destination->server) {
return $this->task->application->destination->server;
}
} elseif ($this->task->service) {
if ($this->task->service->destination && $this->task->service->destination->server) {
return $this->task->service->destination->server;
}
}
return null;
}
public function getServerTimezone()
{
$server = $this->server();
if (!$server) {
return 'UTC';
}
$serverTimezone = $server->settings->server_timezone;
return $serverTimezone;
}
public function formatDateInServerTimezone($date)
{
$serverTimezone = $this->getServerTimezone();
$dateObj = new \DateTime($date);
try {
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
} catch (\Exception $e) {
$dateObj->setTimezone(new \DateTimeZone('UTC'));
}
return $dateObj->format('Y-m-d H:i:s T');
}
}