diff --git a/app/Actions/RemoteProcess/RunRemoteProcess.php b/app/Actions/RemoteProcess/RunRemoteProcess.php index 69dc35465..4a6352041 100644 --- a/app/Actions/RemoteProcess/RunRemoteProcess.php +++ b/app/Actions/RemoteProcess/RunRemoteProcess.php @@ -64,12 +64,14 @@ class RunRemoteProcess { $user = $this->activity->getExtraProperty('user'); $destination = $this->activity->getExtraProperty('destination'); + $private_key_location = $this->activity->getExtraProperty('private_key_location'); $port = $this->activity->getExtraProperty('port'); $command = $this->activity->getExtraProperty('command'); $delimiter = 'EOF-COOLIFY-SSH'; - return 'ssh ' + $ssh_command = "ssh " + . "-i {$private_key_location} " . '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' . '-o PasswordAuthentication=no ' . '-o RequestTTY=no ' @@ -78,6 +80,7 @@ class RunRemoteProcess . " 'bash -se' << \\$delimiter" . PHP_EOL . $command . PHP_EOL . $delimiter; + return $ssh_command; } protected function handleOutput(string $type, string $output) diff --git a/app/Data/RemoteProcessArgs.php b/app/Data/RemoteProcessArgs.php index 65ed0e645..139b94c71 100644 --- a/app/Data/RemoteProcessArgs.php +++ b/app/Data/RemoteProcessArgs.php @@ -10,6 +10,7 @@ class RemoteProcessArgs extends Data { public function __construct( public string $destination, + public string $private_key_location, public string $command, public int $port, public string $user, diff --git a/app/Http/Livewire/RunCommand.php b/app/Http/Livewire/RunCommand.php index db96b17b7..f29b5a29d 100755 --- a/app/Http/Livewire/RunCommand.php +++ b/app/Http/Livewire/RunCommand.php @@ -2,6 +2,7 @@ namespace App\Http\Livewire; +use App\Models\Server; use Livewire\Component; class RunCommand extends Component @@ -16,6 +17,12 @@ class RunCommand extends Component public $server = 'testing-host'; + public $servers = []; + + public function mount() + { + $this->servers = Server::all()->pluck('name')->toArray(); + } public function render() { return view('livewire.run-command'); diff --git a/app/Jobs/ExecuteRemoteProcess.php b/app/Jobs/ExecuteRemoteProcess.php index 567c88d9a..3915c2d55 100755 --- a/app/Jobs/ExecuteRemoteProcess.php +++ b/app/Jobs/ExecuteRemoteProcess.php @@ -31,5 +31,6 @@ class ExecuteRemoteProcess implements ShouldQueue ]); $remoteProcess(); + // @TODO: Remove file at $this->activity->getExtraProperty('private_key_location') after process is finished } } diff --git a/app/Models/PrivateKey.php b/app/Models/PrivateKey.php index 6da73fc87..2f148b1ce 100644 --- a/app/Models/PrivateKey.php +++ b/app/Models/PrivateKey.php @@ -4,8 +4,13 @@ namespace App\Models; class PrivateKey extends BaseModel { - public function private_key_morph() + public function private_keyables() { - return $this->morphTo(); + return $this->hasMany(PrivateKeyable::class); + } + + public function servers() + { + return $this->morphedByMany(Server::class, 'private_keyable'); } } diff --git a/app/Models/Server.php b/app/Models/Server.php index 8e025a75e..a703f8003 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -4,8 +4,8 @@ namespace App\Models; class Server extends BaseModel { - public function private_key() + public function privateKeys() { - return $this->morphMany(PrivateKey::class, 'private_key_morph'); + return $this->morphToMany(PrivateKey::class, 'private_keyable'); } } diff --git a/bootstrap/helpers.php b/bootstrap/helpers.php index e2b9e64ed..6f9b04cad 100644 --- a/bootstrap/helpers.php +++ b/bootstrap/helpers.php @@ -3,11 +3,12 @@ use App\Actions\RemoteProcess\DispatchRemoteProcess; use App\Data\RemoteProcessArgs; use App\Models\Server; +use Illuminate\Support\Facades\Storage; use Spatie\Activitylog\Contracts\Activity; if (!function_exists('remoteProcess')) { /** - * Run a Coolify 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 * */ @@ -15,21 +16,36 @@ if (!function_exists('remoteProcess')) { string $command, string $destination ): Activity { - $found_server = Server::where('name', $destination)->first(); - if (!$found_server) { - throw new \RuntimeException('Server not found.'); - } - $found_team = auth()->user()->teams->pluck('id')->contains($found_server->team_id); - if (!$found_team) { - throw new \RuntimeException('You do not have access to this server.'); - } + $found_server = checkServer($destination); + checkTeam($found_server->team_id); + + $temp_file = 'id.rsa_'.'root'.'@'.$found_server->ip; + Storage::disk('local')->put($temp_file, $found_server->privateKeys->first()->private_key, 'private'); + $private_key_location = '/var/www/html/storage/app/'.$temp_file; + return resolve(DispatchRemoteProcess::class, [ 'remoteProcessArgs' => new RemoteProcessArgs( destination: $found_server->ip, + private_key_location: $private_key_location, command: $command, port: $found_server->port, user: $found_server->user, ), ])(); } + function checkServer(string $destination){ + // @TODO: Use UUID instead of name + $found_server = Server::where('name', $destination)->first(); + if (!$found_server) { + throw new \RuntimeException('Server not found.'); + }; + return $found_server; + } + function checkTeam(string $team_id){ + $found_team = auth()->user()->teams->pluck('id')->contains($team_id); + if (!$found_team) { + throw new \RuntimeException('You do not have access to this server.'); + } + + } } diff --git a/database/migrations/2023_03_24_140853_create_private_keys_table.php b/database/migrations/2023_03_24_140853_create_private_keys_table.php index 3304ed918..09c6ab0ee 100644 --- a/database/migrations/2023_03_24_140853_create_private_keys_table.php +++ b/database/migrations/2023_03_24_140853_create_private_keys_table.php @@ -17,7 +17,7 @@ return new class extends Migration $table->string('name'); $table->string('description')->nullable(); $table->longText('private_key'); - $table->nullableMorphs('private_key_morph'); + $table->nullableMorphs('private_keys_morph'); $table->timestamps(); }); } diff --git a/database/migrations/2023_03_24_203356_create_private_keyables_table.php b/database/migrations/2023_03_24_203356_create_private_keyables_table.php new file mode 100644 index 000000000..7c110413c --- /dev/null +++ b/database/migrations/2023_03_24_203356_create_private_keyables_table.php @@ -0,0 +1,30 @@ +id(); + $table->unsignedBigInteger('private_key_id'); + $table->unsignedBigInteger('private_keyable_id'); + $table->string('private_keyable_type'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('private_keyables'); + } +}; diff --git a/database/seeders/PrivateKeySeeder.php b/database/seeders/PrivateKeySeeder.php index 522c4c703..d3ffc6574 100644 --- a/database/seeders/PrivateKeySeeder.php +++ b/database/seeders/PrivateKeySeeder.php @@ -15,16 +15,20 @@ class PrivateKeySeeder extends Seeder public function run(): void { $server = Server::find(1); - PrivateKey::create([ + $server2 = Server::find(2); + $private_key = PrivateKey::create([ "name" => "Testing-host", "description" => "This is a test docker container", - "private_key" => "-----BEGIN OPENSSH PRIVATE KEY-----\ - b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\ - QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk\ - hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA\ - AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV\ - uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==\ - -----END OPENSSH PRIVATE KEY-----", - ])->private_key_morph()->associate($server)->save(); + "private_key" => "-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk +hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA +AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV +uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== +-----END OPENSSH PRIVATE KEY----- +", + ]); + $server->privateKeys()->attach($private_key); + $server2->privateKeys()->attach($private_key); } } diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index 8d1499689..22fb68a03 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -22,5 +22,12 @@ class ServerSeeder extends Seeder 'ip' => "coolify-testing-host", 'team_id' => $root_team->id, ]); + Server::create([ + 'id' => 2, + 'name' => "testing-host2", + 'description' => "This is a test docker container", + 'ip' => "coolify-testing-host-2", + 'team_id' => $root_team->id, + ]); } } diff --git a/docker-compose.yaml b/docker-compose.yaml index 253554a26..2b1379e2d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -53,6 +53,17 @@ services: - ./docker/testing-host/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf networks: - coolify + testing-host2: + container_name: coolify-testing-host-2 + image: coolify-testing-host + build: + dockerfile: Dockerfile + context: ./docker/testing-host + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./docker/testing-host/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf + networks: + - coolify volumes: db-coolify: diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 239bf9fa8..1959a9b12 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -56,16 +56,6 @@ RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2 RUN groupadd --force -g $WWWGROUP sail RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail -USER sail -RUN mkdir -p ~/.ssh -RUN echo "-----BEGIN OPENSSH PRIVATE KEY-----\n\ -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n\ -QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk\n\ -hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA\n\ -AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV\n\ -uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==\n\ ------END OPENSSH PRIVATE KEY-----" >> ~/.ssh/id_ed25519 -RUN chmod 0600 ~/.ssh/id_ed25519 USER root @@ -78,7 +68,7 @@ RUN chmod +x /usr/local/bin/start-container RUN mkdir -p ~/.docker/cli-plugins RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/docker-$DOCKER_VERSION -o /usr/bin/docker RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/docker-compose-linux-$DOCKER_COMPOSE_VERSION -o ~/.docker/cli-plugins/docker-compose -o /home/sail/.docker/cli-plugins/docker-compose -RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/pack-$PACK_VERSION -o /usr/local/bin/pack +RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/pack-$PACK_VERSION -o /usr/local/bin/pack RUN curl -sSL https://nixpacks.com/install.sh | bash RUN chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker /usr/local/bin/pack diff --git a/resources/views/livewire/run-command.blade.php b/resources/views/livewire/run-command.blade.php index 704c467ea..bac5248e3 100755 --- a/resources/views/livewire/run-command.blade.php +++ b/resources/views/livewire/run-command.blade.php @@ -1,11 +1,14 @@
-