fix
This commit is contained in:
parent
a0306f3951
commit
167379b0e0
@ -100,7 +100,7 @@ protected function getCommand(): string
|
|||||||
$port = $this->activity->getExtraProperty('port');
|
$port = $this->activity->getExtraProperty('port');
|
||||||
$command = $this->activity->getExtraProperty('command');
|
$command = $this->activity->getExtraProperty('command');
|
||||||
|
|
||||||
return generateSshCommand($private_key_location, $server_ip, $user, $port, $command);
|
return generate_ssh_command($private_key_location, $server_ip, $user, $port, $command);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleOutput(string $type, string $output)
|
protected function handleOutput(string $type, string $output)
|
||||||
|
@ -11,7 +11,7 @@ class CheckProxySettingsInSync
|
|||||||
public function __invoke(Server $server, bool $reset = false)
|
public function __invoke(Server $server, bool $reset = false)
|
||||||
{
|
{
|
||||||
$proxy_path = config('coolify.proxy_config_path');
|
$proxy_path = config('coolify.proxy_config_path');
|
||||||
$output = instantRemoteProcess([
|
$output = instant_remote_process([
|
||||||
"cat $proxy_path/docker-compose.yml",
|
"cat $proxy_path/docker-compose.yml",
|
||||||
], $server, false);
|
], $server, false);
|
||||||
if (is_null($output) || $reset) {
|
if (is_null($output) || $reset) {
|
||||||
@ -23,7 +23,7 @@ public function __invoke(Server $server, bool $reset = false)
|
|||||||
$server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
|
$server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
|
||||||
$server->save();
|
$server->save();
|
||||||
if (is_null($output) || $reset) {
|
if (is_null($output) || $reset) {
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"mkdir -p $proxy_path",
|
"mkdir -p $proxy_path",
|
||||||
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
|
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
|
||||||
], $server);
|
], $server);
|
||||||
|
@ -25,7 +25,7 @@ public function __invoke(Server $server): Activity
|
|||||||
return "docker network ls --format '{{.Name}}' | grep '^$network$' >/dev/null 2>&1 || docker network create --attachable $network > /dev/null 2>&1";
|
return "docker network ls --format '{{.Name}}' | grep '^$network$' >/dev/null 2>&1 || docker network create --attachable $network > /dev/null 2>&1";
|
||||||
});
|
});
|
||||||
|
|
||||||
$configuration = instantRemoteProcess([
|
$configuration = instant_remote_process([
|
||||||
"cat $proxy_path/docker-compose.yml",
|
"cat $proxy_path/docker-compose.yml",
|
||||||
], $server, false);
|
], $server, false);
|
||||||
if (is_null($configuration)) {
|
if (is_null($configuration)) {
|
||||||
@ -40,7 +40,7 @@ public function __invoke(Server $server): Activity
|
|||||||
$env_file_base64 = base64_encode(
|
$env_file_base64 = base64_encode(
|
||||||
$this->getEnvContents()
|
$this->getEnvContents()
|
||||||
);
|
);
|
||||||
$activity = remoteProcess([
|
$activity = remote_process([
|
||||||
...$create_networks_command,
|
...$create_networks_command,
|
||||||
"echo 'Docker networks created...'",
|
"echo 'Docker networks created...'",
|
||||||
"mkdir -p $proxy_path",
|
"mkdir -p $proxy_path",
|
||||||
|
@ -10,7 +10,7 @@ class InstallDocker
|
|||||||
public function __invoke(Server $server)
|
public function __invoke(Server $server)
|
||||||
{
|
{
|
||||||
$config = base64_encode('{ "live-restore": true }');
|
$config = base64_encode('{ "live-restore": true }');
|
||||||
$activity = remoteProcess([
|
$activity = remote_process([
|
||||||
"echo Installing Docker...",
|
"echo Installing Docker...",
|
||||||
"curl https://releases.rancher.com/install-docker/23.0.sh | sh",
|
"curl https://releases.rancher.com/install-docker/23.0.sh | sh",
|
||||||
"echo Configuring Docker...",
|
"echo Configuring Docker...",
|
||||||
|
@ -25,8 +25,8 @@ public function delete()
|
|||||||
if ($this->destination->attachedTo()) {
|
if ($this->destination->attachedTo()) {
|
||||||
return $this->emit('error', 'You must delete all resources before deleting this destination.');
|
return $this->emit('error', 'You must delete all resources before deleting this destination.');
|
||||||
}
|
}
|
||||||
instantRemoteProcess(["docker network disconnect {$this->destination->network} coolify-proxy"], $this->destination->server, throwError: false);
|
instant_remote_process(["docker network disconnect {$this->destination->network} coolify-proxy"], $this->destination->server, throwError: false);
|
||||||
instantRemoteProcess(['docker network rm -f ' . $this->destination->network], $this->destination->server);
|
instant_remote_process(['docker network rm -f ' . $this->destination->network], $this->destination->server);
|
||||||
}
|
}
|
||||||
$this->destination->delete();
|
$this->destination->delete();
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
|
@ -45,8 +45,8 @@ public function submit()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$server = Server::find($this->server_id);
|
$server = Server::find($this->server_id);
|
||||||
instantRemoteProcess(['docker network create --attachable ' . $this->network], $server, throwError: false);
|
instant_remote_process(['docker network create --attachable ' . $this->network], $server, throwError: false);
|
||||||
instantRemoteProcess(["docker network connect $this->network coolify-proxy"], $server, throwError: false);
|
instant_remote_process(["docker network connect $this->network coolify-proxy"], $server, throwError: false);
|
||||||
|
|
||||||
$docker = ModelsStandaloneDocker::create([
|
$docker = ModelsStandaloneDocker::create([
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
|
@ -15,10 +15,10 @@ public function upgrade()
|
|||||||
if (!$server) {
|
if (!$server) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"sleep 2"
|
"sleep 2"
|
||||||
], $server);
|
], $server);
|
||||||
remoteProcess([
|
remote_process([
|
||||||
"sleep 10"
|
"sleep 10"
|
||||||
], $server, ActivityTypes::INLINE->value);
|
], $server, ActivityTypes::INLINE->value);
|
||||||
$this->emit('updateInitiated');
|
$this->emit('updateInitiated');
|
||||||
@ -31,18 +31,18 @@ public function upgrade()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml",
|
"curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml",
|
||||||
"curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml",
|
"curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml",
|
||||||
"curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production",
|
"curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production",
|
||||||
"curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
"curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
||||||
], $server);
|
], $server);
|
||||||
|
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull",
|
"docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull",
|
||||||
], $server);
|
], $server);
|
||||||
|
|
||||||
remoteProcess([
|
remote_process([
|
||||||
"bash /data/coolify/source/upgrade.sh $latestVersion"
|
"bash /data/coolify/source/upgrade.sh $latestVersion"
|
||||||
], $server, ActivityTypes::INLINE->value);
|
], $server, ActivityTypes::INLINE->value);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public function delete()
|
|||||||
{
|
{
|
||||||
$destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
|
$destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
|
||||||
|
|
||||||
instantRemoteProcess(["docker rm -f {$this->application->uuid}"], $destination->server);
|
instant_remote_process(["docker rm -f {$this->application->uuid}"], $destination->server);
|
||||||
$this->application->delete();
|
$this->application->delete();
|
||||||
return redirect()->route('project.resources', [
|
return redirect()->route('project.resources', [
|
||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
|
@ -42,13 +42,13 @@ public function loadImages()
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$image = $this->application->uuid;
|
$image = $this->application->uuid;
|
||||||
$output = instantRemoteProcess([
|
$output = instant_remote_process([
|
||||||
"docker inspect --format='{{.Config.Image}}' {$this->application->uuid}",
|
"docker inspect --format='{{.Config.Image}}' {$this->application->uuid}",
|
||||||
], $this->application->destination->server, throwError: false);
|
], $this->application->destination->server, throwError: false);
|
||||||
$current_tag = Str::of($output)->trim()->explode(":");
|
$current_tag = Str::of($output)->trim()->explode(":");
|
||||||
$this->current = data_get($current_tag, 1);
|
$this->current = data_get($current_tag, 1);
|
||||||
|
|
||||||
$output = instantRemoteProcess([
|
$output = instant_remote_process([
|
||||||
"docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}'",
|
"docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}'",
|
||||||
], $this->application->destination->server);
|
], $this->application->destination->server);
|
||||||
$this->images = Str::of($output)->trim()->explode("\n")->filter(function ($item) use ($image) {
|
$this->images = Str::of($output)->trim()->explode("\n")->filter(function ($item) use ($image) {
|
||||||
|
@ -26,7 +26,7 @@ public function runCommand()
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->validate();
|
$this->validate();
|
||||||
$activity = remoteProcess([$this->command], Server::where('uuid', $this->server)->first(), ActivityTypes::INLINE->value);
|
$activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ActivityTypes::INLINE->value);
|
||||||
$this->emit('newMonitorActivity', $activity->id);
|
$this->emit('newMonitorActivity', $activity->id);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return general_error_handler($e);
|
return general_error_handler($e);
|
||||||
|
@ -36,7 +36,7 @@ public function installDocker()
|
|||||||
public function validateServer()
|
public function validateServer()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->uptime = instantRemoteProcess(['uptime'], $this->server, false);
|
$this->uptime = instant_remote_process(['uptime'], $this->server, false);
|
||||||
if (!$this->uptime) {
|
if (!$this->uptime) {
|
||||||
$this->uptime = 'Server not reachable.';
|
$this->uptime = 'Server not reachable.';
|
||||||
throw new \Exception('Server not reachable.');
|
throw new \Exception('Server not reachable.');
|
||||||
@ -47,11 +47,11 @@ public function validateServer()
|
|||||||
$this->emit('serverValidated');
|
$this->emit('serverValidated');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->dockerVersion = instantRemoteProcess(['docker version|head -2|grep -i version'], $this->server, false);
|
$this->dockerVersion = instant_remote_process(['docker version|head -2|grep -i version'], $this->server, false);
|
||||||
if (!$this->dockerVersion) {
|
if (!$this->dockerVersion) {
|
||||||
$this->dockerVersion = 'Not installed.';
|
$this->dockerVersion = 'Not installed.';
|
||||||
}
|
}
|
||||||
$this->dockerComposeVersion = instantRemoteProcess(['docker compose version|head -2|grep -i version'], $this->server, false);
|
$this->dockerComposeVersion = instant_remote_process(['docker compose version|head -2|grep -i version'], $this->server, false);
|
||||||
if (!$this->dockerComposeVersion) {
|
if (!$this->dockerComposeVersion) {
|
||||||
$this->dockerComposeVersion = 'Not installed.';
|
$this->dockerComposeVersion = 'Not installed.';
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ public function setProxy()
|
|||||||
}
|
}
|
||||||
public function stopProxy()
|
public function stopProxy()
|
||||||
{
|
{
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"docker rm -f coolify-proxy",
|
"docker rm -f coolify-proxy",
|
||||||
], $this->server);
|
], $this->server);
|
||||||
$this->server->extra_attributes->proxy_status = 'exited';
|
$this->server->extra_attributes->proxy_status = 'exited';
|
||||||
@ -65,7 +65,7 @@ public function saveConfiguration()
|
|||||||
$docker_compose_yml_base64 = base64_encode($this->proxy_settings);
|
$docker_compose_yml_base64 = base64_encode($this->proxy_settings);
|
||||||
$this->server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
|
$this->server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
|
||||||
$this->server->save();
|
$this->server->save();
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
|
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
|
||||||
], $this->server);
|
], $this->server);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
@ -60,7 +60,7 @@ public function __construct(
|
|||||||
|
|
||||||
$server = $this->destination->server;
|
$server = $this->destination->server;
|
||||||
|
|
||||||
$private_key_location = savePrivateKeyForServer($server);
|
$private_key_location = save_private_key_for_server($server);
|
||||||
|
|
||||||
$remoteProcessArgs = new CoolifyTaskArgs(
|
$remoteProcessArgs = new CoolifyTaskArgs(
|
||||||
server_ip: $server->ip,
|
server_ip: $server->ip,
|
||||||
@ -452,13 +452,13 @@ private function execute_now(
|
|||||||
if ($isDebuggable && !$this->application->settings->is_debug) {
|
if ($isDebuggable && !$this->application->settings->is_debug) {
|
||||||
$hideFromOutput = true;
|
$hideFromOutput = true;
|
||||||
}
|
}
|
||||||
$remoteProcess = resolve(RunRemoteProcess::class, [
|
$remote_process = resolve(RunRemoteProcess::class, [
|
||||||
'activity' => $this->activity,
|
'activity' => $this->activity,
|
||||||
'hideFromOutput' => $hideFromOutput,
|
'hideFromOutput' => $hideFromOutput,
|
||||||
'isFinished' => $isFinished,
|
'isFinished' => $isFinished,
|
||||||
'ignoreErrors' => $ignoreErrors,
|
'ignoreErrors' => $ignoreErrors,
|
||||||
]);
|
]);
|
||||||
$result = $remoteProcess();
|
$result = $remote_process();
|
||||||
if ($propertyName) {
|
if ($propertyName) {
|
||||||
$this->activity->properties = $this->activity->properties->merge([
|
$this->activity->properties = $this->activity->properties->merge([
|
||||||
$propertyName => trim($result->output()),
|
$propertyName => trim($result->output()),
|
||||||
|
@ -47,7 +47,7 @@ protected function check_all_servers()
|
|||||||
$not_found_applications = $applications;
|
$not_found_applications = $applications;
|
||||||
$containers = collect();
|
$containers = collect();
|
||||||
foreach ($servers as $server) {
|
foreach ($servers as $server) {
|
||||||
$output = instantRemoteProcess(['docker ps -a -q --format \'{{json .}}\''], $server);
|
$output = instant_remote_process(['docker ps -a -q --format \'{{json .}}\''], $server);
|
||||||
$containers = $containers->concat(format_docker_command_output_to_json($output));
|
$containers = $containers->concat(format_docker_command_output_to_json($output));
|
||||||
}
|
}
|
||||||
foreach ($containers as $container) {
|
foreach ($containers as $container) {
|
||||||
|
@ -29,7 +29,7 @@ public function handle(): void
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$application = Application::find($this->application_id)->first();
|
$application = Application::find($this->application_id)->first();
|
||||||
instantRemoteProcess(["docker rm -f {$application->uuid}"], $this->server);
|
instant_remote_process(["docker rm -f {$application->uuid}"], $this->server);
|
||||||
$application->status = get_container_status(server: $application->destination->server, container_id: $application->uuid);
|
$application->status = get_container_status(server: $application->destination->server, container_id: $application->uuid);
|
||||||
$application->save();
|
$application->save();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
@ -19,18 +19,19 @@ class CoolifyTask implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public Activity $activity,
|
public Activity $activity,
|
||||||
){}
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the job.
|
* Execute the job.
|
||||||
*/
|
*/
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$remoteProcess = resolve(RunRemoteProcess::class, [
|
$remote_process = resolve(RunRemoteProcess::class, [
|
||||||
'activity' => $this->activity,
|
'activity' => $this->activity,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$remoteProcess();
|
$remote_process();
|
||||||
// @TODO: Remove file at $this->activity->getExtraProperty('private_key_location') after process is finished
|
// @TODO: Remove file at $this->activity->getExtraProperty('private_key_location') after process is finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,10 @@ public function handle(): void
|
|||||||
if (!$server) {
|
if (!$server) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"sleep 2"
|
"sleep 2"
|
||||||
], $server);
|
], $server);
|
||||||
remoteProcess([
|
remote_process([
|
||||||
"sleep 10"
|
"sleep 10"
|
||||||
], $server, ActivityTypes::INLINE->value);
|
], $server, ActivityTypes::INLINE->value);
|
||||||
} else {
|
} else {
|
||||||
@ -68,18 +68,18 @@ public function handle(): void
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml",
|
"curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml",
|
||||||
"curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml",
|
"curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml",
|
||||||
"curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production",
|
"curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production",
|
||||||
"curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
"curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
||||||
], $server);
|
], $server);
|
||||||
|
|
||||||
instantRemoteProcess([
|
instant_remote_process([
|
||||||
"docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull",
|
"docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull",
|
||||||
], $server);
|
], $server);
|
||||||
|
|
||||||
remoteProcess([
|
remote_process([
|
||||||
"bash /data/coolify/source/upgrade.sh $latest_version"
|
"bash /data/coolify/source/upgrade.sh $latest_version"
|
||||||
], $server, ActivityTypes::INLINE->value);
|
], $server, ActivityTypes::INLINE->value);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public function handle(): void
|
|||||||
try {
|
try {
|
||||||
$servers = Server::all();
|
$servers = Server::all();
|
||||||
foreach ($servers as $server) {
|
foreach ($servers as $server) {
|
||||||
instantRemoteProcess(['docker image prune -f'], $server);
|
instant_remote_process(['docker image prune -f'], $server);
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
|
@ -27,7 +27,7 @@ public function register(): void
|
|||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
Queue::after(function (JobProcessed $event) {
|
Queue::after(function (JobProcessed $event) {
|
||||||
// @TODO: Remove `coolify-builder` container after the remoteProcess job is finishged and remoteProcess->type == `deployment`.
|
// @TODO: Remove `coolify-builder` container after the remote_process job is finishged and remote_process->type == `deployment`.
|
||||||
if ($event->job->resolveName() === CoolifyTask::class) {
|
if ($event->job->resolveName() === CoolifyTask::class) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -31,7 +31,7 @@ function format_docker_labels_to_json($rawOutput): Collection
|
|||||||
|
|
||||||
function get_container_status(Server $server, string $container_id, bool $throwError = false)
|
function get_container_status(Server $server, string $container_id, bool $throwError = false)
|
||||||
{
|
{
|
||||||
$container = instantRemoteProcess(["docker inspect --format '{{json .State}}' {$container_id}"], $server, $throwError);
|
$container = instant_remote_process(["docker inspect --format '{{json .State}}' {$container_id}"], $server, $throwError);
|
||||||
if (!$container) {
|
if (!$container) {
|
||||||
return 'exited';
|
return 'exited';
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Actions\CoolifyTask\PrepareCoolifyTask;
|
||||||
use App\Data\CoolifyTaskArgs;
|
use App\Data\CoolifyTaskArgs;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@ -7,96 +8,87 @@
|
|||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Spatie\Activitylog\Models\Activity;
|
use Spatie\Activitylog\Models\Activity;
|
||||||
|
|
||||||
if (!function_exists('remoteProcess')) {
|
/**
|
||||||
/**
|
* Run a Remote Process, which SSH's asynchronously into a machine to run the command(s).
|
||||||
* Run a Remote Process, which SSH's asynchronously into a machine to run the command(s).
|
* @TODO Change 'root' to 'coolify' when it's able to run Docker commands without sudo
|
||||||
* @TODO Change 'root' to 'coolify' when it's able to run Docker commands without sudo
|
*
|
||||||
*
|
*/
|
||||||
*/
|
function remote_process(
|
||||||
function remoteProcess(
|
array $command,
|
||||||
array $command,
|
Server $server,
|
||||||
Server $server,
|
string $type,
|
||||||
string $type,
|
?string $type_uuid = null,
|
||||||
?string $type_uuid = null,
|
?Model $model = null,
|
||||||
?Model $model = null,
|
): Activity {
|
||||||
): Activity {
|
|
||||||
|
|
||||||
$command_string = implode("\n", $command);
|
$command_string = implode("\n", $command);
|
||||||
|
|
||||||
// @TODO: Check if the user has access to this server
|
// @TODO: Check if the user has access to this server
|
||||||
// checkTeam($server->team_id);
|
// checkTeam($server->team_id);
|
||||||
|
|
||||||
$private_key_location = savePrivateKeyForServer($server);
|
$private_key_location = save_private_key_for_server($server);
|
||||||
|
|
||||||
return resolve(PrepareCoolifyTask::class, [
|
return resolve(PrepareCoolifyTask::class, [
|
||||||
'remoteProcessArgs' => new CoolifyTaskArgs(
|
'remoteProcessArgs' => new CoolifyTaskArgs(
|
||||||
server_ip: $server->ip,
|
server_ip: $server->ip,
|
||||||
private_key_location: $private_key_location,
|
private_key_location: $private_key_location,
|
||||||
command: <<<EOT
|
command: <<<EOT
|
||||||
{$command_string}
|
{$command_string}
|
||||||
EOT,
|
EOT,
|
||||||
port: $server->port,
|
port: $server->port,
|
||||||
user: $server->user,
|
user: $server->user,
|
||||||
type: $type,
|
type: $type,
|
||||||
type_uuid: $type_uuid,
|
type_uuid: $type_uuid,
|
||||||
model: $model,
|
model: $model,
|
||||||
),
|
),
|
||||||
])();
|
])();
|
||||||
}
|
}
|
||||||
|
function save_private_key_for_server(Server $server)
|
||||||
|
{
|
||||||
|
$temp_file = "id.root@{$server->ip}";
|
||||||
|
Storage::disk('ssh-keys')->put($temp_file, $server->privateKey->private_key);
|
||||||
|
return '/var/www/html/storage/app/ssh-keys/' . $temp_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!function_exists('savePrivateKeyForServer')) {
|
function generate_ssh_command(string $private_key_location, string $server_ip, string $user, string $port, string $command, bool $isMux = true)
|
||||||
function savePrivateKeyForServer(Server $server)
|
{
|
||||||
{
|
Storage::disk('local')->makeDirectory('.ssh');
|
||||||
$temp_file = "id.root@{$server->ip}";
|
|
||||||
Storage::disk('ssh-keys')->put($temp_file, $server->privateKey->private_key);
|
$delimiter = 'EOF-COOLIFY-SSH';
|
||||||
return '/var/www/html/storage/app/ssh-keys/' . $temp_file;
|
$ssh_command = "ssh ";
|
||||||
|
|
||||||
|
if ($isMux && config('coolify.mux_enabled')) {
|
||||||
|
$ssh_command .= '-o ControlMaster=auto -o ControlPersist=1m -o ControlPath=/var/www/html/storage/app/.ssh/ssh_mux_%h_%p_%r ';
|
||||||
}
|
}
|
||||||
|
$ssh_command .= "-i {$private_key_location} "
|
||||||
|
. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
||||||
|
. '-o PasswordAuthentication=no '
|
||||||
|
. '-o ConnectTimeout=3600 '
|
||||||
|
. '-o ServerAliveInterval=20 '
|
||||||
|
. '-o RequestTTY=no '
|
||||||
|
. '-o LogLevel=ERROR '
|
||||||
|
. "-p {$port} "
|
||||||
|
. "{$user}@{$server_ip} "
|
||||||
|
. " 'bash -se' << \\$delimiter" . PHP_EOL
|
||||||
|
. $command . PHP_EOL
|
||||||
|
. $delimiter;
|
||||||
|
|
||||||
|
return $ssh_command;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!function_exists('generateSshCommand')) {
|
function instant_remote_process(array $command, Server $server, $throwError = true)
|
||||||
function generateSshCommand(string $private_key_location, string $server_ip, string $user, string $port, string $command, bool $isMux = true)
|
{
|
||||||
{
|
$command_string = implode("\n", $command);
|
||||||
Storage::disk('local')->makeDirectory('.ssh');
|
$private_key_location = save_private_key_for_server($server);
|
||||||
|
$ssh_command = generate_ssh_command($private_key_location, $server->ip, $server->user, $server->port, $command_string);
|
||||||
$delimiter = 'EOF-COOLIFY-SSH';
|
$process = Process::run($ssh_command);
|
||||||
$ssh_command = "ssh ";
|
$output = trim($process->output());
|
||||||
|
$exitCode = $process->exitCode();
|
||||||
if ($isMux && config('coolify.mux_enabled')) {
|
if ($exitCode !== 0) {
|
||||||
$ssh_command .= '-o ControlMaster=auto -o ControlPersist=1m -o ControlPath=/var/www/html/storage/app/.ssh/ssh_mux_%h_%p_%r ';
|
if (!$throwError) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
$ssh_command .= "-i {$private_key_location} "
|
throw new \RuntimeException($process->errorOutput());
|
||||||
. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
|
||||||
. '-o PasswordAuthentication=no '
|
|
||||||
. '-o ConnectTimeout=3600 '
|
|
||||||
. '-o ServerAliveInterval=20 '
|
|
||||||
. '-o RequestTTY=no '
|
|
||||||
. '-o LogLevel=ERROR '
|
|
||||||
. "-p {$port} "
|
|
||||||
. "{$user}@{$server_ip} "
|
|
||||||
. " 'bash -se' << \\$delimiter" . PHP_EOL
|
|
||||||
. $command . PHP_EOL
|
|
||||||
. $delimiter;
|
|
||||||
|
|
||||||
return $ssh_command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!function_exists('instantRemoteProcess')) {
|
|
||||||
function instantRemoteProcess(array $command, Server $server, $throwError = true)
|
|
||||||
{
|
|
||||||
$command_string = implode("\n", $command);
|
|
||||||
$private_key_location = savePrivateKeyForServer($server);
|
|
||||||
$ssh_command = generateSshCommand($private_key_location, $server->ip, $server->user, $server->port, $command_string);
|
|
||||||
$process = Process::run($ssh_command);
|
|
||||||
$output = trim($process->output());
|
|
||||||
$exitCode = $process->exitCode();
|
|
||||||
if ($exitCode !== 0) {
|
|
||||||
if (!$throwError) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw new \RuntimeException($process->errorOutput());
|
|
||||||
}
|
|
||||||
return $output;
|
|
||||||
}
|
}
|
||||||
|
return $output;
|
||||||
}
|
}
|
||||||
|
@ -33,28 +33,28 @@
|
|||||||
$containerName = 'coolify_test_' . now()->format('Ymd_his');
|
$containerName = 'coolify_test_' . now()->format('Ymd_his');
|
||||||
$host = Server::where('name', 'testing-local-docker-container')->first();
|
$host = Server::where('name', 'testing-local-docker-container')->first();
|
||||||
|
|
||||||
remoteProcess([
|
remote_process([
|
||||||
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq) > /dev/null 2>&1"
|
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq) > /dev/null 2>&1"
|
||||||
], $host);
|
], $host);
|
||||||
|
|
||||||
// Assert there's no containers start with coolify_test_*
|
// Assert there's no containers start with coolify_test_*
|
||||||
$activity = remoteProcess([$areThereCoolifyTestContainers], $host);
|
$activity = remote_process([$areThereCoolifyTestContainers], $host);
|
||||||
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
||||||
$containers = format_docker_command_output_to_json($tidyOutput);
|
$containers = format_docker_command_output_to_json($tidyOutput);
|
||||||
expect($containers)->toBeEmpty();
|
expect($containers)->toBeEmpty();
|
||||||
|
|
||||||
// start a container nginx -d --name = $containerName
|
// start a container nginx -d --name = $containerName
|
||||||
$activity = remoteProcess(["docker run -d --rm --name {$containerName} nginx"], $host);
|
$activity = remote_process(["docker run -d --rm --name {$containerName} nginx"], $host);
|
||||||
expect($activity->getExtraProperty('exitCode'))->toBe(0);
|
expect($activity->getExtraProperty('exitCode'))->toBe(0);
|
||||||
|
|
||||||
// docker ps name = $container
|
// docker ps name = $container
|
||||||
$activity = remoteProcess([$areThereCoolifyTestContainers], $host);
|
$activity = remote_process([$areThereCoolifyTestContainers], $host);
|
||||||
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
||||||
$containers = format_docker_command_output_to_json($tidyOutput);
|
$containers = format_docker_command_output_to_json($tidyOutput);
|
||||||
expect($containers->where('Names', $containerName)->count())->toBe(1);
|
expect($containers->where('Names', $containerName)->count())->toBe(1);
|
||||||
|
|
||||||
// Stop testing containers
|
// Stop testing containers
|
||||||
$activity = remoteProcess([
|
$activity = remote_process([
|
||||||
"docker ps --filter='name={$coolifyNamePrefix}*' -aq && " .
|
"docker ps --filter='name={$coolifyNamePrefix}*' -aq && " .
|
||||||
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq)"
|
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq)"
|
||||||
], $host);
|
], $host);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
$host = Server::where('name', 'testing-local-docker-container')->first();
|
$host = Server::where('name', 'testing-local-docker-container')->first();
|
||||||
|
|
||||||
$activity = remoteProcess([
|
$activity = remote_process([
|
||||||
'pwd',
|
'pwd',
|
||||||
'x=1; while [ $x -le 3 ]; do sleep 0.1 && echo "Welcome $x times" $(( x++ )); done',
|
'x=1; while [ $x -le 3 ]; do sleep 0.1 && echo "Welcome $x times" $(( x++ )); done',
|
||||||
], $host);
|
], $host);
|
||||||
|
Loading…
Reference in New Issue
Block a user