Merge pull request #3950 from peaklabs-dev/fix-postgres-init-scripts
Fix: Multiple Init script fixes and some other Postgres fixes
This commit is contained in:
@@ -23,6 +23,9 @@ class StartPostgresql
|
|||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
$container_name = $this->database->uuid;
|
$container_name = $this->database->uuid;
|
||||||
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
|
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
|
||||||
|
if (isDev()) {
|
||||||
|
$this->configuration_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/databases/'.$container_name;
|
||||||
|
}
|
||||||
|
|
||||||
$this->commands = [
|
$this->commands = [
|
||||||
"echo 'Starting database.'",
|
"echo 'Starting database.'",
|
||||||
@@ -78,7 +81,7 @@ class StartPostgresql
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
if (! is_null($this->database->limits_cpuset)) {
|
if (filled($this->database->limits_cpuset)) {
|
||||||
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
|
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
|
||||||
}
|
}
|
||||||
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
|
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
|
||||||
@@ -108,7 +111,7 @@ class StartPostgresql
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! is_null($this->database->postgres_conf) && ! empty($this->database->postgres_conf)) {
|
if (filled($this->database->postgres_conf)) {
|
||||||
$docker_compose['services'][$container_name]['volumes'][] = [
|
$docker_compose['services'][$container_name]['volumes'][] = [
|
||||||
'type' => 'bind',
|
'type' => 'bind',
|
||||||
'source' => $this->configuration_dir.'/custom-postgres.conf',
|
'source' => $this->configuration_dir.'/custom-postgres.conf',
|
||||||
@@ -199,9 +202,12 @@ class StartPostgresql
|
|||||||
|
|
||||||
private function generate_init_scripts()
|
private function generate_init_scripts()
|
||||||
{
|
{
|
||||||
if (is_null($this->database->init_scripts) || count($this->database->init_scripts) === 0) {
|
$this->commands[] = "rm -rf $this->configuration_dir/docker-entrypoint-initdb.d/*";
|
||||||
|
|
||||||
|
if (blank($this->database->init_scripts) || count($this->database->init_scripts) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->database->init_scripts as $init_script) {
|
foreach ($this->database->init_scripts as $init_script) {
|
||||||
$filename = data_get($init_script, 'filename');
|
$filename = data_get($init_script, 'filename');
|
||||||
$content = data_get($init_script, 'content');
|
$content = data_get($init_script, 'content');
|
||||||
@@ -213,10 +219,15 @@ class StartPostgresql
|
|||||||
|
|
||||||
private function add_custom_conf()
|
private function add_custom_conf()
|
||||||
{
|
{
|
||||||
if (is_null($this->database->postgres_conf) || empty($this->database->postgres_conf)) {
|
$filename = 'custom-postgres.conf';
|
||||||
|
$config_file_path = "$this->configuration_dir/$filename";
|
||||||
|
|
||||||
|
if (blank($this->database->postgres_conf)) {
|
||||||
|
$this->commands[] = "rm -f $config_file_path";
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$filename = 'custom-postgres.conf';
|
|
||||||
$content = $this->database->postgres_conf;
|
$content = $this->database->postgres_conf;
|
||||||
if (! str($content)->contains('listen_addresses')) {
|
if (! str($content)->contains('listen_addresses')) {
|
||||||
$content .= "\nlisten_addresses = '*'";
|
$content .= "\nlisten_addresses = '*'";
|
||||||
@@ -224,6 +235,6 @@ class StartPostgresql
|
|||||||
$this->database->save();
|
$this->database->save();
|
||||||
}
|
}
|
||||||
$content_base64 = base64_encode($content);
|
$content_base64 = base64_encode($content);
|
||||||
$this->commands[] = "echo '{$content_base64}' | base64 -d | tee $this->configuration_dir/{$filename} > /dev/null";
|
$this->commands[] = "echo '{$content_base64}' | base64 -d | tee $config_file_path > /dev/null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,6 @@ use App\Models\StandalonePostgresql;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
use function Aws\filter;
|
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
public StandalonePostgresql $database;
|
public StandalonePostgresql $database;
|
||||||
@@ -126,10 +124,52 @@ class General extends Component
|
|||||||
|
|
||||||
public function save_init_script($script)
|
public function save_init_script($script)
|
||||||
{
|
{
|
||||||
$this->database->init_scripts = filter($this->database->init_scripts, fn ($s) => $s['filename'] !== $script['filename']);
|
$initScripts = collect($this->database->init_scripts ?? []);
|
||||||
$this->database->init_scripts = array_merge($this->database->init_scripts, [$script]);
|
|
||||||
|
$existingScript = $initScripts->firstWhere('filename', $script['filename']);
|
||||||
|
$oldScript = $initScripts->firstWhere('index', $script['index']);
|
||||||
|
|
||||||
|
if ($existingScript && $existingScript['index'] !== $script['index']) {
|
||||||
|
$this->dispatch('error', 'A script with this filename already exists.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$container_name = $this->database->uuid;
|
||||||
|
$configuration_dir = database_configuration_dir().'/'.$container_name;
|
||||||
|
|
||||||
|
if ($oldScript && $oldScript['filename'] !== $script['filename']) {
|
||||||
|
$old_file_path = "$configuration_dir/docker-entrypoint-initdb.d/{$oldScript['filename']}";
|
||||||
|
$delete_command = "rm -f $old_file_path";
|
||||||
|
try {
|
||||||
|
instant_remote_process([$delete_command], $this->server);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->dispatch('error', 'Failed to remove old init script from server: '.$e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$index = $initScripts->search(function ($item) use ($script) {
|
||||||
|
return $item['index'] === $script['index'];
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($index !== false) {
|
||||||
|
$initScripts[$index] = $script;
|
||||||
|
} else {
|
||||||
|
$initScripts->push($script);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->database->init_scripts = $initScripts->values()
|
||||||
|
->map(function ($item, $index) {
|
||||||
|
$item['index'] = $index;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
})
|
||||||
|
->all();
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'Init script saved.');
|
$this->dispatch('success', 'Init script saved and updated.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete_init_script($script)
|
public function delete_init_script($script)
|
||||||
@@ -137,13 +177,33 @@ class General extends Component
|
|||||||
$collection = collect($this->database->init_scripts);
|
$collection = collect($this->database->init_scripts);
|
||||||
$found = $collection->firstWhere('filename', $script['filename']);
|
$found = $collection->firstWhere('filename', $script['filename']);
|
||||||
if ($found) {
|
if ($found) {
|
||||||
$this->database->init_scripts = $collection->filter(fn ($s) => $s['filename'] !== $script['filename'])->toArray();
|
$container_name = $this->database->uuid;
|
||||||
$this->database->save();
|
$configuration_dir = database_configuration_dir().'/'.$container_name;
|
||||||
$this->refresh();
|
$file_path = "$configuration_dir/docker-entrypoint-initdb.d/{$script['filename']}";
|
||||||
$this->dispatch('success', 'Init script deleted.');
|
|
||||||
|
$command = "rm -f $file_path";
|
||||||
|
try {
|
||||||
|
instant_remote_process([$command], $this->server);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->dispatch('error', 'Failed to remove init script from server: '.$e->getMessage());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$updatedScripts = $collection->filter(fn ($s) => $s['filename'] !== $script['filename'])
|
||||||
|
->values()
|
||||||
|
->map(function ($item, $index) {
|
||||||
|
$item['index'] = $index;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
})
|
||||||
|
->all();
|
||||||
|
|
||||||
|
$this->database->init_scripts = $updatedScripts;
|
||||||
|
$this->database->save();
|
||||||
|
$this->refresh();
|
||||||
|
$this->dispatch('success', 'Init script deleted from the database and the server.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function refresh(): void
|
public function refresh(): void
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<x-forms.button type="submit">Save</x-forms.button>
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
<x-modal-confirmation title="Confirm init-script deletion?" buttonTitle="Delete" isErrorButton
|
<x-modal-confirmation title="Confirm init-script deletion?" buttonTitle="Delete" isErrorButton
|
||||||
submitAction="delete" :actions="[
|
submitAction="delete" :actions="[
|
||||||
'The init-script of this database will be permanently deleted.',
|
'The init-script of this database will be permanently deleted form the database and the server.',
|
||||||
'If you are actively using this init-script, it could cause errors on redeployment.',
|
'If you are actively using this init-script, it could cause errors on redeployment.',
|
||||||
]" confirmationText="{{ $filename }}"
|
]" confirmationText="{{ $filename }}"
|
||||||
confirmationLabel="Please confirm the execution of the actions by entering the init-script name below"
|
confirmationLabel="Please confirm the execution of the actions by entering the init-script name below"
|
||||||
|
Reference in New Issue
Block a user