Add Servers and PrivateKeys
Add new testhost Remove privatekey injection from Dockerfile
This commit is contained in:
parent
9e326d15b9
commit
f57684b024
@ -64,12 +64,14 @@ protected function getCommand(): string
|
|||||||
{
|
{
|
||||||
$user = $this->activity->getExtraProperty('user');
|
$user = $this->activity->getExtraProperty('user');
|
||||||
$destination = $this->activity->getExtraProperty('destination');
|
$destination = $this->activity->getExtraProperty('destination');
|
||||||
|
$private_key_location = $this->activity->getExtraProperty('private_key_location');
|
||||||
$port = $this->activity->getExtraProperty('port');
|
$port = $this->activity->getExtraProperty('port');
|
||||||
$command = $this->activity->getExtraProperty('command');
|
$command = $this->activity->getExtraProperty('command');
|
||||||
|
|
||||||
$delimiter = 'EOF-COOLIFY-SSH';
|
$delimiter = 'EOF-COOLIFY-SSH';
|
||||||
|
|
||||||
return 'ssh '
|
$ssh_command = "ssh "
|
||||||
|
. "-i {$private_key_location} "
|
||||||
. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
||||||
. '-o PasswordAuthentication=no '
|
. '-o PasswordAuthentication=no '
|
||||||
. '-o RequestTTY=no '
|
. '-o RequestTTY=no '
|
||||||
@ -78,6 +80,7 @@ protected function getCommand(): string
|
|||||||
. " 'bash -se' << \\$delimiter" . PHP_EOL
|
. " 'bash -se' << \\$delimiter" . PHP_EOL
|
||||||
. $command . PHP_EOL
|
. $command . PHP_EOL
|
||||||
. $delimiter;
|
. $delimiter;
|
||||||
|
return $ssh_command;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleOutput(string $type, string $output)
|
protected function handleOutput(string $type, string $output)
|
||||||
|
@ -10,6 +10,7 @@ class RemoteProcessArgs extends Data
|
|||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $destination,
|
public string $destination,
|
||||||
|
public string $private_key_location,
|
||||||
public string $command,
|
public string $command,
|
||||||
public int $port,
|
public int $port,
|
||||||
public string $user,
|
public string $user,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Livewire;
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class RunCommand extends Component
|
class RunCommand extends Component
|
||||||
@ -16,6 +17,12 @@ class RunCommand extends Component
|
|||||||
|
|
||||||
public $server = 'testing-host';
|
public $server = 'testing-host';
|
||||||
|
|
||||||
|
public $servers = [];
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->servers = Server::all()->pluck('name')->toArray();
|
||||||
|
}
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.run-command');
|
return view('livewire.run-command');
|
||||||
|
@ -31,5 +31,6 @@ public function handle(): void
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$remoteProcess();
|
$remoteProcess();
|
||||||
|
// @TODO: Remove file at $this->activity->getExtraProperty('private_key_location') after process is finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,13 @@
|
|||||||
|
|
||||||
class PrivateKey extends BaseModel
|
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
class Server extends BaseModel
|
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
use App\Actions\RemoteProcess\DispatchRemoteProcess;
|
use App\Actions\RemoteProcess\DispatchRemoteProcess;
|
||||||
use App\Data\RemoteProcessArgs;
|
use App\Data\RemoteProcessArgs;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Spatie\Activitylog\Contracts\Activity;
|
use Spatie\Activitylog\Contracts\Activity;
|
||||||
|
|
||||||
if (!function_exists('remoteProcess')) {
|
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
|
* @TODO Change 'root' to 'coolify' when it's able to run Docker commands without sudo
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -15,21 +16,36 @@ function remoteProcess(
|
|||||||
string $command,
|
string $command,
|
||||||
string $destination
|
string $destination
|
||||||
): Activity {
|
): Activity {
|
||||||
$found_server = Server::where('name', $destination)->first();
|
$found_server = checkServer($destination);
|
||||||
if (!$found_server) {
|
checkTeam($found_server->team_id);
|
||||||
throw new \RuntimeException('Server not found.');
|
|
||||||
}
|
$temp_file = 'id.rsa_'.'root'.'@'.$found_server->ip;
|
||||||
$found_team = auth()->user()->teams->pluck('id')->contains($found_server->team_id);
|
Storage::disk('local')->put($temp_file, $found_server->privateKeys->first()->private_key, 'private');
|
||||||
if (!$found_team) {
|
$private_key_location = '/var/www/html/storage/app/'.$temp_file;
|
||||||
throw new \RuntimeException('You do not have access to this server.');
|
|
||||||
}
|
|
||||||
return resolve(DispatchRemoteProcess::class, [
|
return resolve(DispatchRemoteProcess::class, [
|
||||||
'remoteProcessArgs' => new RemoteProcessArgs(
|
'remoteProcessArgs' => new RemoteProcessArgs(
|
||||||
destination: $found_server->ip,
|
destination: $found_server->ip,
|
||||||
|
private_key_location: $private_key_location,
|
||||||
command: $command,
|
command: $command,
|
||||||
port: $found_server->port,
|
port: $found_server->port,
|
||||||
user: $found_server->user,
|
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.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public function up(): void
|
|||||||
$table->string('name');
|
$table->string('name');
|
||||||
$table->string('description')->nullable();
|
$table->string('description')->nullable();
|
||||||
$table->longText('private_key');
|
$table->longText('private_key');
|
||||||
$table->nullableMorphs('private_key_morph');
|
$table->nullableMorphs('private_keys_morph');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<?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::create('private_keyables', function (Blueprint $table) {
|
||||||
|
$table->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');
|
||||||
|
}
|
||||||
|
};
|
@ -15,16 +15,20 @@ class PrivateKeySeeder extends Seeder
|
|||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$server = Server::find(1);
|
$server = Server::find(1);
|
||||||
PrivateKey::create([
|
$server2 = Server::find(2);
|
||||||
|
$private_key = PrivateKey::create([
|
||||||
"name" => "Testing-host",
|
"name" => "Testing-host",
|
||||||
"description" => "This is a test docker container",
|
"description" => "This is a test docker container",
|
||||||
"private_key" => "-----BEGIN OPENSSH PRIVATE KEY-----\
|
"private_key" => "-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||||
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk\
|
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk
|
||||||
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA\
|
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA
|
||||||
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV\
|
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
|
||||||
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==\
|
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||||
-----END OPENSSH PRIVATE KEY-----",
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
])->private_key_morph()->associate($server)->save();
|
",
|
||||||
|
]);
|
||||||
|
$server->privateKeys()->attach($private_key);
|
||||||
|
$server2->privateKeys()->attach($private_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,12 @@ public function run(): void
|
|||||||
'ip' => "coolify-testing-host",
|
'ip' => "coolify-testing-host",
|
||||||
'team_id' => $root_team->id,
|
'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,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,17 @@ services:
|
|||||||
- ./docker/testing-host/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf
|
- ./docker/testing-host/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf
|
||||||
networks:
|
networks:
|
||||||
- coolify
|
- 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:
|
volumes:
|
||||||
db-coolify:
|
db-coolify:
|
||||||
|
@ -56,16 +56,6 @@ RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2
|
|||||||
RUN groupadd --force -g $WWWGROUP sail
|
RUN groupadd --force -g $WWWGROUP sail
|
||||||
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 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
|
USER root
|
||||||
|
|
||||||
@ -78,7 +68,7 @@ RUN chmod +x /usr/local/bin/start-container
|
|||||||
RUN mkdir -p ~/.docker/cli-plugins
|
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-$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/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 curl -sSL https://nixpacks.com/install.sh | bash
|
||||||
|
|
||||||
RUN chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker /usr/local/bin/pack
|
RUN chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker /usr/local/bin/pack
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label for="command">
|
<label for="command">
|
||||||
<input autofocus id="command" wire:model="command" type="text" wire:keydown.enter="runCommand" />
|
<input autofocus id="command" wire:model.defer="command" type="text" wire:keydown.enter="runCommand" />
|
||||||
<input id="command" wire:model="server" type="text" />
|
<select wire:model.defer="server">
|
||||||
|
@foreach ($servers as $server)
|
||||||
|
<option value="{{ $server }}">{{ $server }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<button wire:click="runCommand">Run command</button>
|
<button wire:click="runCommand">Run command</button>
|
||||||
|
|
||||||
<button wire:click="runSleepingBeauty">Run sleeping beauty</button>
|
<button wire:click="runSleepingBeauty">Run sleeping beauty</button>
|
||||||
<button wire:click="runDummyProjectBuild">Build DummyProject</button>
|
<button wire:click="runDummyProjectBuild">Build DummyProject</button>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user