wip
This commit is contained in:
@@ -28,7 +28,7 @@ class SyncBunny extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$bunny_cdn = "https://coolify-cdn.b-cdn.net/";
|
||||
$bunny_cdn = "https://coolify-cdn.b-cdn.net";
|
||||
$bunny_cdn_path = "files";
|
||||
$bunny_cdn_storage_name = "coolify-cdn";
|
||||
|
||||
@@ -36,10 +36,13 @@ class SyncBunny extends Command
|
||||
|
||||
$compose_file = "docker-compose.yml";
|
||||
$compose_file_prod = "docker-compose.prod.yml";
|
||||
$install_script = "install.sh";
|
||||
$upgrade_script = "upgrade.sh";
|
||||
$docker_install_script = "install-docker.sh";
|
||||
$production_env = ".env.production";
|
||||
|
||||
$versions = "versions.json";
|
||||
|
||||
PendingRequest::macro('storage', function ($file) {
|
||||
$headers = [
|
||||
'AccessKey' => env('BUNNY_STORAGE_API_KEY'),
|
||||
@@ -50,29 +53,36 @@ class SyncBunny extends Command
|
||||
$file = fread($fileStream, filesize($file));
|
||||
return PendingRequest::baseUrl('https://storage.bunnycdn.com')->withHeaders($headers)->withBody($file)->throw();
|
||||
});
|
||||
PendingRequest::macro('purge', function ($url) {
|
||||
$headers = [
|
||||
'AccessKey' => env('BUNNY_API_KEY'),
|
||||
'Accept' => 'application/json',
|
||||
];
|
||||
return PendingRequest::withHeaders($headers)->post('https://api.bunny.net/purge', [
|
||||
"urls" => [$url],
|
||||
]);
|
||||
});
|
||||
try {
|
||||
Http::pool(fn (Pool $pool) => [
|
||||
$pool->storage(file: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"),
|
||||
$pool->storage(file: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"),
|
||||
$pool->storage(file: "$parent_dir/$production_env")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$production_env"),
|
||||
$pool->storage(file: "$parent_dir/scripts/$upgrade_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$upgrade_script"),
|
||||
$pool->storage(file: "$parent_dir/scripts/$install_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$install_script"),
|
||||
$pool->storage(file: "$parent_dir/scripts/$docker_install_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$docker_install_script"),
|
||||
$pool->storage(file: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$versions"),
|
||||
]);
|
||||
|
||||
$res = Http::withHeaders([
|
||||
'AccessKey' => env('BUNNY_API_KEY'),
|
||||
'Accept' => 'application/json',
|
||||
])->get('https://api.bunny.net/purge', [
|
||||
"url" => "$bunny_cdn/$bunny_cdn_path/$compose_file",
|
||||
"url" => "$bunny_cdn/$bunny_cdn_path/$compose_file_prod",
|
||||
"url" => "$bunny_cdn/$bunny_cdn_path/$upgrade_script",
|
||||
"url" => "$bunny_cdn/$bunny_cdn_path/$production_env",
|
||||
"url" => "$bunny_cdn/$bunny_cdn_path/$docker_install_script"
|
||||
Http::pool(fn (Pool $pool) => [
|
||||
$pool->purge(url: "$bunny_cdn/$bunny_cdn_path/$compose_file"),
|
||||
$pool->purge(url: "$bunny_cdn/$bunny_cdn_path/$compose_file_prod"),
|
||||
$pool->purge(url: "$bunny_cdn/$bunny_cdn_path/$production_env"),
|
||||
$pool->purge(url: "$bunny_cdn/$bunny_cdn_path/$upgrade_script"),
|
||||
$pool->purge(url: "$bunny_cdn/$bunny_cdn_path/$install_script"),
|
||||
$pool->purge(url: "$bunny_cdn/$bunny_cdn_path/$docker_install_script"),
|
||||
$pool->purge(url: "$bunny_cdn/$versions"),
|
||||
]);
|
||||
if ($res->ok()) {
|
||||
echo "All files uploaded & purged...\n";
|
||||
return;
|
||||
}
|
||||
echo "All files uploaded & purged...\n";
|
||||
return;
|
||||
throw new \Exception("Something went wrong.");
|
||||
} catch (\Exception $e) {
|
||||
echo $e->getMessage();
|
||||
|
||||
@@ -20,7 +20,7 @@ class CoolifyTaskArgs extends Data
|
||||
public string $type,
|
||||
public ?string $type_uuid = null,
|
||||
public ?Model $model = null,
|
||||
public string $status = ProcessStatus::HOLDING->value,
|
||||
public string $status = ProcessStatus::QUEUED->value,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Enums;
|
||||
|
||||
enum ProcessStatus: string
|
||||
{
|
||||
case HOLDING = 'holding';
|
||||
case QUEUED = 'queued';
|
||||
case IN_PROGRESS = 'in_progress';
|
||||
case FINISHED = 'finished';
|
||||
case ERROR = 'error';
|
||||
|
||||
@@ -21,7 +21,7 @@ class ApplicationController extends Controller
|
||||
if (!$application) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
return view('project.application.configuration', ['application' => $application]);
|
||||
return view('project.application.configuration', ['application' => $application,]);
|
||||
}
|
||||
public function deployments()
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ class ProjectController extends Controller
|
||||
return view('project.environments', ['project' => $project]);
|
||||
}
|
||||
|
||||
public function resources_new()
|
||||
public function new()
|
||||
{
|
||||
$project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
||||
if (!$project) {
|
||||
@@ -29,7 +29,12 @@ class ProjectController extends Controller
|
||||
if (!$environment) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
return view('project.new', ['project' => $project, 'environment' => $environment, 'type' => 'resource']);
|
||||
|
||||
$type = request()->query('type');
|
||||
|
||||
return view('project.new', [
|
||||
'type' => $type
|
||||
]);
|
||||
}
|
||||
public function resources()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Enums\ProcessStatus;
|
||||
use Livewire\Component;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
|
||||
@@ -31,12 +32,24 @@ class ActivityMonitor extends Component
|
||||
public function polling()
|
||||
{
|
||||
$this->hydrateActivity();
|
||||
|
||||
if (data_get($this->activity, 'properties.exitCode') !== null) {
|
||||
$this->setStatus(ProcessStatus::IN_PROGRESS);
|
||||
$exit_code = data_get($this->activity, 'properties.exitCode');
|
||||
if ($exit_code !== null) {
|
||||
if ($exit_code === 0) {
|
||||
$this->setStatus(ProcessStatus::FINISHED);
|
||||
} else {
|
||||
$this->setStatus(ProcessStatus::ERROR);
|
||||
}
|
||||
$this->isPollingActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function setStatus($status)
|
||||
{
|
||||
$this->activity->properties = $this->activity->properties->merge([
|
||||
'status' => $status,
|
||||
]);
|
||||
$this->activity->save();
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.activity-monitor');
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Livewire\Component;
|
||||
|
||||
class CheckUpdate extends Component
|
||||
@@ -16,7 +14,7 @@ class CheckUpdate extends Component
|
||||
public function checkUpdate()
|
||||
{
|
||||
$this->latestVersion = getLatestVersionOfCoolify();
|
||||
$this->currentVersion = config('coolify.version');
|
||||
$this->currentVersion = config('version');
|
||||
if ($this->latestVersion === 'latest') {
|
||||
$this->updateAvailable = true;
|
||||
return;
|
||||
|
||||
@@ -22,7 +22,7 @@ class Form extends Component
|
||||
}
|
||||
public function delete()
|
||||
{
|
||||
instantRemoteProcess(['docker network rm -f ' . $this->destination->network], $this->destination->server);
|
||||
// instantRemoteProcess(['docker network rm -f ' . $this->destination->network], $this->destination->server);
|
||||
$this->destination->delete();
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class StandaloneDocker extends Component
|
||||
public string $network;
|
||||
|
||||
public Collection $servers;
|
||||
public int $server_id;
|
||||
public int|null $server_id = null;
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required|string',
|
||||
@@ -23,10 +23,14 @@ class StandaloneDocker extends Component
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
if (request()->query('server_id')) {
|
||||
$this->server_id = request()->query('server_id');
|
||||
} else {
|
||||
$this->server_id = Server::first()->id;
|
||||
if (!$this->server_id) {
|
||||
if (request()->query('server_id')) {
|
||||
$this->server_id = request()->query('server_id');
|
||||
} else {
|
||||
if ($this->servers->count() > 0) {
|
||||
$this->server_id = $this->servers->first()->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->network = new Cuid2(7);
|
||||
$this->name = generateRandomName();
|
||||
|
||||
@@ -35,7 +35,7 @@ class Change extends Component
|
||||
$this->private_key->save();
|
||||
session('currentTeam')->privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
|
||||
} catch (\Exception $e) {
|
||||
$this->addError('private_key_value', $e->getMessage());
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
namespace App\Http\Livewire\PrivateKey;
|
||||
|
||||
use App\Models\PrivateKey;
|
||||
use Illuminate\Routing\Route as RoutingRoute;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Component;
|
||||
|
||||
class Create extends Component
|
||||
{
|
||||
public $private_key_value;
|
||||
public $private_key_name;
|
||||
public $private_key_description;
|
||||
public string $name;
|
||||
public string|null $description;
|
||||
public string $value;
|
||||
public string $currentRoute;
|
||||
|
||||
public function mount()
|
||||
@@ -20,14 +19,14 @@ class Create extends Component
|
||||
}
|
||||
public function createPrivateKey()
|
||||
{
|
||||
$this->private_key_value = trim($this->private_key_value);
|
||||
if (!str_ends_with($this->private_key_value, "\n")) {
|
||||
$this->private_key_value .= "\n";
|
||||
$this->value = trim($this->value);
|
||||
if (!str_ends_with($this->value, "\n")) {
|
||||
$this->value .= "\n";
|
||||
}
|
||||
$new_private_key = PrivateKey::create([
|
||||
'name' => $this->private_key_name,
|
||||
'description' => $this->private_key_description,
|
||||
'private_key' => $this->private_key_value,
|
||||
'name' => $this->name,
|
||||
'description' => $this->description,
|
||||
'private_key' => $this->value,
|
||||
'team_id' => session('currentTeam')->id
|
||||
]);
|
||||
session('currentTeam')->privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
|
||||
|
||||
@@ -23,7 +23,7 @@ class Deploy extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
$this->parameters = getParameters();
|
||||
$this->application = Application::where('id', $this->applicationId)->first();
|
||||
$this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class Add extends Component
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
$this->parameters = getParameters();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ class All extends Component
|
||||
$this->application->refresh();
|
||||
$this->emit('clearAddEnv');
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandlerLivewire($e, $this);
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class Show extends Component
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
$this->parameters = getParameters();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@ class General extends Component
|
||||
$this->application->settings->is_dual_cert = $this->is_dual_cert;
|
||||
$this->application->settings->save();
|
||||
$this->application->refresh();
|
||||
$this->emit('saved', 'Application settings updated!');
|
||||
}
|
||||
public function mount()
|
||||
{
|
||||
|
||||
@@ -19,4 +19,13 @@ class Source extends Component
|
||||
{
|
||||
$this->application = Application::where('id', $this->applicationId)->first();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
$this->validate();
|
||||
if (!$this->application->git_commit_sha) {
|
||||
$this->application->git_commit_sha = 'HEAD';
|
||||
}
|
||||
$this->application->save();
|
||||
$this->emit('saved', 'Application source updated!');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class Add extends Component
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
$this->parameters = getParameters();
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ class All extends Component
|
||||
$this->application->refresh();
|
||||
$this->emit('clearAddStorage');
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandlerLivewire($e, $this);
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
app/Http/Livewire/Project/Delete.php
Normal file
25
app/Http/Livewire/Project/Delete.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project;
|
||||
|
||||
use App\Models\Project;
|
||||
use Livewire\Component;
|
||||
|
||||
class Delete extends Component
|
||||
{
|
||||
public int $project_id;
|
||||
public int $resource_count = 0;
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->validate([
|
||||
'project_id' => 'required|int',
|
||||
]);
|
||||
$project = Project::findOrFail($this->project_id);
|
||||
if ($project->applications->count() > 0) {
|
||||
return $this->emit('error', 'Project has applications, please delete them first.');
|
||||
}
|
||||
$project->delete();
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
}
|
||||
142
app/Http/Livewire/Project/New/GithubPrivateRepository.php
Normal file
142
app/Http/Livewire/Project/New/GithubPrivateRepository.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\New;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\SwarmDocker;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Livewire\Component;
|
||||
|
||||
class GithubPrivateRepository extends Component
|
||||
{
|
||||
public $github_apps;
|
||||
public GithubApp $github_app;
|
||||
public $parameters;
|
||||
public $query;
|
||||
public $type;
|
||||
|
||||
public int $selected_repository_id;
|
||||
public string $selected_repository_owner;
|
||||
public string $selected_repository_repo;
|
||||
|
||||
public string $selected_branch_name = 'main';
|
||||
|
||||
public string $token;
|
||||
|
||||
protected int $page = 1;
|
||||
|
||||
public $repositories;
|
||||
public int $total_repositories_count = 0;
|
||||
|
||||
public $branches;
|
||||
public int $total_branches_count = 0;
|
||||
|
||||
protected function loadRepositoryByPage()
|
||||
{
|
||||
$response = Http::withToken($this->token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}");
|
||||
$json = $response->json();
|
||||
if ($response->status() !== 200) {
|
||||
return $this->emit('error', $json['message']);
|
||||
}
|
||||
|
||||
if ($json['total_count'] === 0) {
|
||||
return;
|
||||
}
|
||||
$this->total_repositories_count = $json['total_count'];
|
||||
$this->repositories = $this->repositories->concat(collect($json['repositories']));
|
||||
}
|
||||
protected function loadBranchByPage()
|
||||
{
|
||||
Log::info('Loading page ' . $this->page);
|
||||
$response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}");
|
||||
$json = $response->json();
|
||||
if ($response->status() !== 200) {
|
||||
return $this->emit('error', $json['message']);
|
||||
}
|
||||
|
||||
$this->total_branches_count = count($json);
|
||||
$this->branches = $this->branches->concat(collect($json));
|
||||
}
|
||||
public function loadRepositories($github_app_id)
|
||||
{
|
||||
$this->repositories = collect();
|
||||
$this->page = 1;
|
||||
$this->github_app = GithubApp::where('id', $github_app_id)->first();
|
||||
$this->token = generate_github_installation_token($this->github_app);
|
||||
$this->loadRepositoryByPage();
|
||||
if ($this->repositories->count() < $this->total_repositories_count) {
|
||||
while ($this->repositories->count() < $this->total_repositories_count) {
|
||||
$this->page++;
|
||||
$this->loadRepositoryByPage();
|
||||
}
|
||||
}
|
||||
$this->selected_repository_id = $this->repositories[0]['id'];
|
||||
}
|
||||
public function loadBranches()
|
||||
{
|
||||
$this->selected_repository_owner = $this->repositories->where('id', $this->selected_repository_id)->first()['owner']['login'];
|
||||
$this->selected_repository_repo = $this->repositories->where('id', $this->selected_repository_id)->first()['name'];
|
||||
$this->branches = collect();
|
||||
$this->page = 1;
|
||||
$this->loadBranchByPage();
|
||||
if ($this->total_branches_count === 100) {
|
||||
while ($this->total_branches_count === 100) {
|
||||
$this->page++;
|
||||
$this->loadBranchByPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$destination_uuid = $this->query['destination'];
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
$destination = SwarmDocker::where('uuid', $destination_uuid)->first();
|
||||
}
|
||||
if (!$destination) {
|
||||
throw new \Exception('Destination not found. What?!');
|
||||
}
|
||||
$destination_class = $destination->getMorphClass();
|
||||
|
||||
|
||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
||||
|
||||
$application = Application::create([
|
||||
'name' => generateRandomName() . "-{$this->selected_repository_owner}/{$this->selected_repository_repo}:{$this->selected_branch_name}",
|
||||
'repository_project_id' => $this->selected_repository_id,
|
||||
'git_repository' => "{$this->selected_repository_owner}/{$this->selected_repository_repo}",
|
||||
'git_branch' => $this->selected_branch_name,
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination_class,
|
||||
'source_id' => $this->github_app->id,
|
||||
'source_type' => GithubApp::class,
|
||||
]);
|
||||
|
||||
redirect()->route('project.application.configuration', [
|
||||
'application_uuid' => $application->uuid,
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_name' => $environment->name
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = getParameters();
|
||||
$this->query = request()->query();
|
||||
$this->repositories = $this->branches = collect();
|
||||
$this->github_apps = GithubApp::private();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project\New;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\SwarmDocker;
|
||||
use Livewire\Component;
|
||||
use Spatie\Url\Url;
|
||||
|
||||
class GithubPrivateRepositoryDeployKey extends Component
|
||||
{
|
||||
public $parameters;
|
||||
public $query;
|
||||
public $private_keys;
|
||||
public int $private_key_id;
|
||||
public string $repository_url;
|
||||
|
||||
public int $port = 3000;
|
||||
public string $type;
|
||||
|
||||
public bool $is_static = false;
|
||||
public null|string $publish_directory = null;
|
||||
protected $rules = [
|
||||
'repository_url' => 'required|url',
|
||||
'port' => 'required|numeric',
|
||||
'is_static' => 'required|boolean',
|
||||
'publish_directory' => 'nullable|string',
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
if (config('app.env') === 'local') {
|
||||
$this->repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify';
|
||||
}
|
||||
$this->parameters = getParameters();
|
||||
$this->query = request()->query();
|
||||
$this->private_keys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
|
||||
}
|
||||
public function instantSave()
|
||||
{
|
||||
if ($this->is_static) {
|
||||
$this->port = 80;
|
||||
$this->publish_directory = '/dist';
|
||||
} else {
|
||||
$this->port = 3000;
|
||||
$this->publish_directory = null;
|
||||
}
|
||||
}
|
||||
public function setPrivateKey($private_key_id)
|
||||
{
|
||||
$this->private_key_id = $private_key_id;
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->validate();
|
||||
$url = Url::fromString($this->repository_url);
|
||||
$git_host = $url->getHost();
|
||||
$git_repository = $url->getSegment(1) . '/' . $url->getSegment(2);
|
||||
$git_branch = $url->getSegment(4) ?? 'main';
|
||||
|
||||
$destination_uuid = $this->query['destination'];
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
$destination = SwarmDocker::where('uuid', $destination_uuid)->first();
|
||||
}
|
||||
if (!$destination) {
|
||||
throw new \Exception('Destination not found. What?!');
|
||||
}
|
||||
$destination_class = $destination->getMorphClass();
|
||||
|
||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
||||
$application_init = [
|
||||
'name' => generateRandomName() . "-{$git_repository}:{$git_branch}",
|
||||
'git_repository' => $git_repository,
|
||||
'git_branch' => $git_branch,
|
||||
'git_full_url' => "git@$git_host:$git_repository.git",
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => $this->port,
|
||||
'publish_directory' => $this->publish_directory,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination_class,
|
||||
'private_key_id' => $this->private_key_id,
|
||||
];
|
||||
$application = Application::create($application_init);
|
||||
$application->settings->is_static = $this->is_static;
|
||||
$application->settings->save();
|
||||
|
||||
return redirect()->route('project.application.configuration', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_name' => $environment->name,
|
||||
'application_uuid' => $application->uuid,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,22 +8,17 @@ use App\Models\GitlabApp;
|
||||
use App\Models\Project;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\SwarmDocker;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Component;
|
||||
use Spatie\Url\Url;
|
||||
|
||||
class PublicGitRepository extends Component
|
||||
{
|
||||
public string $public_repository_url;
|
||||
public int $port;
|
||||
public string $repository_url;
|
||||
public int $port = 3000;
|
||||
public string $type;
|
||||
public $parameters;
|
||||
public $query;
|
||||
|
||||
public $servers;
|
||||
public $standalone_docker;
|
||||
public $swarm_docker;
|
||||
public $chosenServer;
|
||||
public $chosenDestination;
|
||||
public $github_apps;
|
||||
public $gitlab_apps;
|
||||
|
||||
@@ -31,7 +26,7 @@ class PublicGitRepository extends Component
|
||||
public null|string $publish_directory = null;
|
||||
|
||||
protected $rules = [
|
||||
'public_repository_url' => 'required|url',
|
||||
'repository_url' => 'required|url',
|
||||
'port' => 'required|numeric',
|
||||
'is_static' => 'required|boolean',
|
||||
'publish_directory' => 'nullable|string',
|
||||
@@ -39,23 +34,11 @@ class PublicGitRepository extends Component
|
||||
public function mount()
|
||||
{
|
||||
if (config('app.env') === 'local') {
|
||||
$this->public_repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify';
|
||||
$this->repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify';
|
||||
$this->port = 3000;
|
||||
}
|
||||
$this->parameters = Route::current()->parameters();
|
||||
$this->servers = session('currentTeam')->load(['servers'])->servers;
|
||||
}
|
||||
public function chooseServer($server)
|
||||
{
|
||||
$this->chosenServer = $server;
|
||||
$this->standalone_docker = StandaloneDocker::where('server_id', $server['id'])->get();
|
||||
$this->swarm_docker = SwarmDocker::where('server_id', $server['id'])->get();
|
||||
}
|
||||
public function setDestination($destination_uuid, $destination_type)
|
||||
{
|
||||
$class = "App\Models\\{$destination_type}";
|
||||
$instance = new $class;
|
||||
$this->chosenDestination = $instance::where('uuid', $destination_uuid)->first();
|
||||
$this->parameters = getParameters();
|
||||
$this->query = request()->query();
|
||||
}
|
||||
|
||||
public function instantSave()
|
||||
@@ -67,53 +50,63 @@ class PublicGitRepository extends Component
|
||||
$this->port = 3000;
|
||||
$this->publish_directory = null;
|
||||
}
|
||||
$this->emit('saved', 'Application settings updated!');
|
||||
}
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->validate();
|
||||
$url = Url::fromString($this->public_repository_url);
|
||||
$git_host = $url->getHost();
|
||||
$git_repository = $url->getSegment(1) . '/' . $url->getSegment(2);
|
||||
$git_branch = $url->getSegment(4) ?? 'main';
|
||||
try {
|
||||
$this->validate();
|
||||
|
||||
if ($this->type === 'project') {
|
||||
$project = Project::create([
|
||||
'name' => generateRandomName(),
|
||||
'team_id' => session('currentTeam')->id,
|
||||
$url = Url::fromString($this->repository_url);
|
||||
$git_host = $url->getHost();
|
||||
$git_repository = $url->getSegment(1) . '/' . $url->getSegment(2);
|
||||
$git_branch = $url->getSegment(4) ?? 'main';
|
||||
|
||||
$destination_uuid = $this->query['destination'];
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
$destination = SwarmDocker::where('uuid', $destination_uuid)->first();
|
||||
}
|
||||
if (!$destination) {
|
||||
throw new \Exception('Destination not found. What?!');
|
||||
}
|
||||
$destination_class = $destination->getMorphClass();
|
||||
|
||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
||||
|
||||
|
||||
$application_init = [
|
||||
'name' => generateRandomName() . "-{$git_repository}:{$git_branch}",
|
||||
'git_repository' => $git_repository,
|
||||
'git_branch' => $git_branch,
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => $this->port,
|
||||
'publish_directory' => $this->publish_directory,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination_class,
|
||||
];
|
||||
if ($git_host == 'github.com') {
|
||||
$application_init['source_id'] = GithubApp::where('name', 'Public GitHub')->first()->id;
|
||||
$application_init['source_type'] = GithubApp::class;
|
||||
} elseif ($git_host == 'gitlab.com') {
|
||||
$application_init['source_id'] = GitlabApp::where('name', 'Public GitLab')->first()->id;
|
||||
$application_init['source_type'] = GitlabApp::class;
|
||||
} elseif ($git_host == 'bitbucket.org') {
|
||||
}
|
||||
$application = Application::create($application_init);
|
||||
$application->settings->is_static = $this->is_static;
|
||||
$application->settings->save();
|
||||
|
||||
return redirect()->route('project.application.configuration', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_name' => $environment->name,
|
||||
'application_uuid' => $application->uuid,
|
||||
]);
|
||||
$environment = $project->environments->first();
|
||||
} else {
|
||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->firstOrFail();
|
||||
$environment = $project->environments->where('name', $this->parameters['environment_name'])->firstOrFail();
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e);
|
||||
}
|
||||
$application_init = [
|
||||
'name' => generateRandomName(),
|
||||
'git_repository' => $git_repository,
|
||||
'git_branch' => $git_branch,
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => $this->port,
|
||||
'publish_directory' => $this->publish_directory,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $this->chosenDestination->id,
|
||||
'destination_type' => $this->chosenDestination->getMorphClass(),
|
||||
];
|
||||
if ($git_host == 'github.com') {
|
||||
$application_init['source_id'] = GithubApp::where('name', 'Public GitHub')->first()->id;
|
||||
$application_init['source_type'] = GithubApp::class;
|
||||
} elseif ($git_host == 'gitlab.com') {
|
||||
$application_init['source_id'] = GitlabApp::where('name', 'Public GitLab')->first()->id;
|
||||
$application_init['source_type'] = GitlabApp::class;
|
||||
} elseif ($git_host == 'bitbucket.org') {
|
||||
}
|
||||
$application = Application::create($application_init);
|
||||
$application->settings->is_static = $this->is_static;
|
||||
$application->settings->save();
|
||||
|
||||
return redirect()->route('project.application.configuration', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_name' => $environment->name,
|
||||
'application_uuid' => $application->uuid,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use Livewire\Component;
|
||||
|
||||
class RunCommand extends Component
|
||||
{
|
||||
public $command;
|
||||
public string $command;
|
||||
public $server;
|
||||
public $servers = [];
|
||||
|
||||
@@ -16,16 +16,20 @@ class RunCommand extends Component
|
||||
'server' => 'required',
|
||||
'command' => 'required',
|
||||
];
|
||||
public function mount()
|
||||
public function mount($servers)
|
||||
{
|
||||
$this->servers = Server::where('team_id', session('currentTeam')->id)->get();
|
||||
$this->server = $this->servers[0]->uuid;
|
||||
$this->servers = $servers;
|
||||
$this->server = $servers[0]->uuid;
|
||||
}
|
||||
|
||||
public function runCommand()
|
||||
{
|
||||
$this->validate();
|
||||
$activity = remoteProcess([$this->command], Server::where('uuid', $this->server)->first(), ActivityTypes::INLINE->value);
|
||||
$this->emit('newMonitorActivity', $activity->id);
|
||||
try {
|
||||
$this->validate();
|
||||
$activity = remoteProcess([$this->command], Server::where('uuid', $this->server)->first(), ActivityTypes::INLINE->value);
|
||||
$this->emit('newMonitorActivity', $activity->id);
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@ class Form extends Component
|
||||
'server.ip' => 'required',
|
||||
'server.user' => 'required',
|
||||
'server.port' => 'required',
|
||||
'server.settings.is_validated' => 'required'
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->server = Server::find($this->server_id);
|
||||
$this->server = Server::find($this->server_id)->load(['settings']);
|
||||
}
|
||||
public function installDocker()
|
||||
{
|
||||
@@ -38,6 +39,11 @@ class Form extends Component
|
||||
if (!$this->uptime) {
|
||||
$this->uptime = 'Server not reachable.';
|
||||
throw new \Exception('Server not reachable.');
|
||||
} else {
|
||||
if (!$this->server->settings->is_validated) {
|
||||
$this->server->settings->is_validated = true;
|
||||
$this->server->settings->save();
|
||||
}
|
||||
}
|
||||
$this->dockerVersion = instantRemoteProcess(['docker version|head -2|grep -i version'], $this->server, false);
|
||||
if (!$this->dockerVersion) {
|
||||
@@ -48,6 +54,7 @@ class Form extends Component
|
||||
$this->dockerComposeVersion = 'Not installed.';
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
public function delete()
|
||||
|
||||
@@ -9,7 +9,7 @@ use Livewire\Component;
|
||||
class ByIp extends Component
|
||||
{
|
||||
public $private_keys;
|
||||
public int $private_key_id;
|
||||
public int|null $private_key_id = null;
|
||||
public $new_private_key_name;
|
||||
public $new_private_key_description;
|
||||
public $new_private_key_value;
|
||||
@@ -20,30 +20,40 @@ class ByIp extends Component
|
||||
public string $user = 'root';
|
||||
public int $port = 22;
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required',
|
||||
'ip' => 'required',
|
||||
'user' => 'required',
|
||||
'port' => 'required|integer',
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->name = generateRandomName();
|
||||
$this->private_keys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
|
||||
}
|
||||
public function setPrivateKey($private_key_id)
|
||||
public function setPrivateKey(string $private_key_id)
|
||||
{
|
||||
$this->private_key_id = $private_key_id;
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
if (!$this->private_key_id) {
|
||||
$this->addError('private_key_id', 'The private key field is required.');
|
||||
return;
|
||||
try {
|
||||
if (!$this->private_key_id) {
|
||||
return $this->emit('error', 'You must select a private key');
|
||||
}
|
||||
$this->validate();
|
||||
$server = Server::create([
|
||||
'name' => $this->name,
|
||||
'description' => $this->description,
|
||||
'ip' => $this->ip,
|
||||
'user' => $this->user,
|
||||
'port' => $this->port,
|
||||
'team_id' => session('currentTeam')->id,
|
||||
'private_key_id' => $this->private_key_id
|
||||
]);
|
||||
return redirect()->route('server.show', $server->uuid);
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e);
|
||||
}
|
||||
$server = Server::create([
|
||||
'name' => $this->name,
|
||||
'description' => $this->description,
|
||||
'ip' => $this->ip,
|
||||
'user' => $this->user,
|
||||
'port' => $this->port,
|
||||
'team_id' => session('currentTeam')->id,
|
||||
'private_key_id' => $this->private_key_id
|
||||
]);
|
||||
return redirect()->route('server.show', $server->uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class PrivateKey extends Component
|
||||
}
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = Route::current()->parameters();
|
||||
$this->parameters = getParameters();
|
||||
$this->private_keys = ModelsPrivateKey::where('team_id', session('currentTeam')->id)->get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ class Form extends Component
|
||||
$this->settings->is_registration_enabled = $this->is_registration_enabled;
|
||||
$this->settings->is_https_forced = $this->is_https_forced;
|
||||
$this->settings->save();
|
||||
$this->emit('saved', 'Settings updated!');
|
||||
}
|
||||
public function submit()
|
||||
{
|
||||
|
||||
49
app/Http/Livewire/Source/Create.php
Normal file
49
app/Http/Livewire/Source/Create.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Source;
|
||||
|
||||
use App\Models\GithubApp;
|
||||
use Livewire\Component;
|
||||
|
||||
class Create extends Component
|
||||
{
|
||||
public string $name;
|
||||
public string|null $organization = null;
|
||||
public string $api_url = 'https://api.github.com';
|
||||
public string $html_url = 'https://github.com';
|
||||
public string $custom_user = 'git';
|
||||
public int $custom_port = 22;
|
||||
public bool $is_system_wide = false;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->name = generateRandomName();
|
||||
}
|
||||
public function createGitHubApp()
|
||||
{
|
||||
try {
|
||||
$this->validate([
|
||||
"name" => 'required|string',
|
||||
"organization" => 'nullable|string',
|
||||
"api_url" => 'required|string',
|
||||
"html_url" => 'required|string',
|
||||
"custom_user" => 'required|string',
|
||||
"custom_port" => 'required|int',
|
||||
"is_system_wide" => 'required|bool',
|
||||
]);
|
||||
$github_app = GithubApp::create([
|
||||
'name' => $this->name,
|
||||
'organization' => $this->organization,
|
||||
'api_url' => $this->api_url,
|
||||
'html_url' => $this->html_url,
|
||||
'custom_user' => $this->custom_user,
|
||||
'custom_port' => $this->custom_port,
|
||||
'is_system_wide' => $this->is_system_wide,
|
||||
'team_id' => session('currentTeam')->id,
|
||||
]);
|
||||
redirect()->route('source.github.show', ['github_app_uuid' => $github_app->uuid]);
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
app/Http/Livewire/Source/Github/Change.php
Normal file
67
app/Http/Livewire/Source/Github/Change.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Source\Github;
|
||||
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\InstanceSettings;
|
||||
use Livewire\Component;
|
||||
|
||||
class Change extends Component
|
||||
{
|
||||
public string $host;
|
||||
public $parameters;
|
||||
public GithubApp $github_app;
|
||||
public bool $is_system_wide;
|
||||
|
||||
protected $rules = [
|
||||
'github_app.name' => 'required|string',
|
||||
'github_app.organization' => 'nullable|string',
|
||||
'github_app.api_url' => 'required|string',
|
||||
'github_app.html_url' => 'required|string',
|
||||
'github_app.custom_user' => 'required|string',
|
||||
'github_app.custom_port' => 'required|int',
|
||||
'github_app.app_id' => 'required|int',
|
||||
'github_app.installation_id' => 'required|int',
|
||||
'github_app.client_id' => 'required|string',
|
||||
'github_app.client_secret' => 'required|string',
|
||||
'github_app.webhook_secret' => 'required|string',
|
||||
'github_app.is_system_wide' => 'required|bool',
|
||||
];
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->validate();
|
||||
$this->github_app->save();
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
$this->github_app->is_system_wide = $this->is_system_wide;
|
||||
$this->github_app->save();
|
||||
$this->emit('saved', 'GitHub settings updated!');
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
public function mount()
|
||||
{
|
||||
$settings = InstanceSettings::first();
|
||||
if ($settings->fqdn) {
|
||||
$this->host = $settings->fqdn;
|
||||
}
|
||||
$this->parameters = getParameters();
|
||||
$this->is_system_wide = $this->github_app->is_system_wide;
|
||||
}
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$this->github_app->delete();
|
||||
redirect()->route('dashboard');
|
||||
} catch (\Exception $e) {
|
||||
return generalErrorHandler($e, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,20 +7,13 @@ use App\Data\CoolifyTaskArgs;
|
||||
use App\Enums\ActivityTypes;
|
||||
use App\Models\Application;
|
||||
use App\Models\InstanceSettings;
|
||||
use DateTimeImmutable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Lcobucci\JWT\Encoding\ChainedFormatter;
|
||||
use Lcobucci\JWT\Encoding\JoseEncoder;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
use Lcobucci\JWT\Signer\Rsa\Sha256;
|
||||
use Lcobucci\JWT\Token\Builder;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -107,7 +100,10 @@ class DeployApplicationJob implements ShouldQueue
|
||||
{
|
||||
try {
|
||||
$coolify_instance_settings = InstanceSettings::find(0);
|
||||
$this->source = $this->application->source->getMorphClass()::where('id', $this->application->source->id)->first();
|
||||
$deployment_type = $this->application->deploymentType();
|
||||
if ($this->application->deploymentType() === 'source') {
|
||||
$this->source = $this->application->source->getMorphClass()::where('id', $this->application->source->id)->first();
|
||||
}
|
||||
|
||||
// Get Wildcard Domain
|
||||
$project_wildcard_domain = data_get($this->application, 'environment.project.settings.wildcard_domain');
|
||||
@@ -372,34 +368,11 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
|
||||
return implode(' ', $generated_healthchecks_commands);
|
||||
}
|
||||
|
||||
private function generate_jwt_token_for_github()
|
||||
{
|
||||
$signingKey = InMemory::plainText($this->source->privateKey->private_key);
|
||||
$algorithm = new Sha256();
|
||||
$tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
|
||||
$now = new DateTimeImmutable();
|
||||
$now = $now->setTime($now->format('H'), $now->format('i'));
|
||||
$issuedToken = $tokenBuilder
|
||||
->issuedBy($this->source->app_id)
|
||||
->issuedAt($now)
|
||||
->expiresAt($now->modify('+10 minutes'))
|
||||
->getToken($algorithm, $signingKey)
|
||||
->toString();
|
||||
$token = Http::withHeaders([
|
||||
'Authorization' => "Bearer $issuedToken",
|
||||
'Accept' => 'application/vnd.github.machine-man-preview+json'
|
||||
])->post("{$this->source->api_url}/app/installations/{$this->source->installation_id}/access_tokens");
|
||||
if ($token->failed()) {
|
||||
throw new \Exception("Failed to get access token for $this->application->name from " . $this->source->name . " with error: " . $token->json()['message']);
|
||||
}
|
||||
return $token->json()['token'];
|
||||
}
|
||||
|
||||
private function set_labels_for_applications()
|
||||
{
|
||||
$labels = [];
|
||||
$labels[] = 'coolify.managed=true';
|
||||
$labels[] = 'coolify.version=' . config('coolify.version');
|
||||
$labels[] = 'coolify.version=' . config('version');
|
||||
$labels[] = 'coolify.applicationId=' . $this->application->id;
|
||||
$labels[] = 'coolify.type=application';
|
||||
$labels[] = 'coolify.name=' . $this->application->name;
|
||||
@@ -453,8 +426,8 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
|
||||
}
|
||||
private function setGitImportSettings($git_clone_command)
|
||||
{
|
||||
if ($this->application->git_commit_sha) {
|
||||
$git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git checkout {$this->application->git_commit_sha}";
|
||||
if ($this->application->git_commit_sha !== 'HEAD') {
|
||||
$git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git -c advice.detachedHead=false checkout {$this->application->git_commit_sha} >/dev/null 2>&1";
|
||||
}
|
||||
if ($this->application->settings->is_git_submodules_allowed) {
|
||||
$git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git submodule update --init --recursive";
|
||||
@@ -466,41 +439,40 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
|
||||
}
|
||||
private function gitImport()
|
||||
{
|
||||
$source_html_url = data_get($this->application, 'source.html_url');
|
||||
$url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL));
|
||||
$source_html_url_host = $url['host'];
|
||||
$source_html_url_scheme = $url['scheme'];
|
||||
|
||||
$git_clone_command = "git clone -q -b {$this->application->git_branch}";
|
||||
|
||||
if ($this->application->source->getMorphClass() == 'App\Models\GithubApp') {
|
||||
if ($this->source->is_public) {
|
||||
$git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}";
|
||||
$git_clone_command = $this->setGitImportSettings($git_clone_command);
|
||||
return [
|
||||
$this->execute_in_builder($git_clone_command)
|
||||
];
|
||||
} else {
|
||||
if (!$this->application->source->app_id) {
|
||||
$private_key = base64_encode($this->application->source->privateKey->private_key);
|
||||
if ($this->application->deploymentType() === 'source') {
|
||||
$source_html_url = data_get($this->application, 'source.html_url');
|
||||
$url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL));
|
||||
$source_html_url_host = $url['host'];
|
||||
$source_html_url_scheme = $url['scheme'];
|
||||
|
||||
$git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} git@$source_html_url_host:{$this->application->git_repository}.git {$this->workdir}";
|
||||
if ($this->source->getMorphClass() == 'App\Models\GithubApp') {
|
||||
if ($this->source->is_public) {
|
||||
$git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}";
|
||||
$git_clone_command = $this->setGitImportSettings($git_clone_command);
|
||||
|
||||
return [
|
||||
$this->execute_in_builder("mkdir -p /root/.ssh"),
|
||||
$this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"),
|
||||
$this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"),
|
||||
$this->execute_in_builder($git_clone_command)
|
||||
];
|
||||
} else {
|
||||
$github_access_token = $this->generate_jwt_token_for_github();
|
||||
$github_access_token = generate_github_installation_token($this->source);
|
||||
return [
|
||||
$this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->application->deploymentType() === 'deploy_key') {
|
||||
$private_key = base64_encode($this->application->private_key->private_key);
|
||||
$git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}";
|
||||
$git_clone_command = $this->setGitImportSettings($git_clone_command);
|
||||
return [
|
||||
$this->execute_in_builder("mkdir -p /root/.ssh"),
|
||||
$this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"),
|
||||
$this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"),
|
||||
$this->execute_in_builder($git_clone_command)
|
||||
];
|
||||
}
|
||||
}
|
||||
private function nixpacks_build_cmd()
|
||||
{
|
||||
|
||||
@@ -24,9 +24,11 @@ class Application extends BaseModel
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'project_id',
|
||||
'description',
|
||||
'git_repository',
|
||||
'git_branch',
|
||||
'git_full_url',
|
||||
'build_pack',
|
||||
'environment_id',
|
||||
'destination_id',
|
||||
@@ -36,6 +38,7 @@ class Application extends BaseModel
|
||||
'ports_mappings',
|
||||
'ports_exposes',
|
||||
'publish_directory',
|
||||
'private_key_id'
|
||||
];
|
||||
public function publishDirectory(): Attribute
|
||||
{
|
||||
@@ -43,6 +46,28 @@ class Application extends BaseModel
|
||||
set: fn ($value) => $value ? '/' . ltrim($value, '/') : null,
|
||||
);
|
||||
}
|
||||
public function gitBranchLocation(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
if (!is_null($this->source?->html_url) && !is_null($this->git_repository) && !is_null($this->git_branch)) {
|
||||
return "{$this->source->html_url}/{$this->git_repository}/tree/{$this->git_branch}";
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
public function gitCommits(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function () {
|
||||
if (!is_null($this->source?->html_url) && !is_null($this->git_repository) && !is_null($this->git_branch)) {
|
||||
return "{$this->source->html_url}/{$this->git_repository}/commits/{$this->git_branch}";
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
public function baseDirectory(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@@ -90,6 +115,10 @@ class Application extends BaseModel
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('key', 'like', 'NIXPACKS_%');
|
||||
}
|
||||
public function private_key()
|
||||
{
|
||||
return $this->belongsTo(PrivateKey::class);
|
||||
}
|
||||
public function environment()
|
||||
{
|
||||
return $this->belongsTo(Environment::class);
|
||||
@@ -119,4 +148,21 @@ class Application extends BaseModel
|
||||
{
|
||||
return Activity::where('subject_id', $this->id)->where('properties->type_uuid', '=', $deployment_uuid)->first();
|
||||
}
|
||||
public function isDeployable(): bool
|
||||
{
|
||||
if ($this->settings->is_auto_deploy) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function deploymentType()
|
||||
{
|
||||
if (data_get($this, 'source')) {
|
||||
return 'source';
|
||||
}
|
||||
if (data_get($this, 'private_key_id')) {
|
||||
return 'deploy_key';
|
||||
}
|
||||
throw new \Exception('No deployment type found');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ abstract class BaseModel extends Model
|
||||
parent::boot();
|
||||
|
||||
static::creating(function (Model $model) {
|
||||
$model->uuid = (string) new Cuid2(7);
|
||||
// Generate a UUID if one isn't set
|
||||
if (!$model->uuid) {
|
||||
$model->uuid = (string) new Cuid2(7);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Support\Str;
|
||||
|
||||
class EnvironmentVariable extends Model
|
||||
{
|
||||
|
||||
protected $fillable = ['key', 'value', 'is_build_time', 'application_id'];
|
||||
protected $casts = [
|
||||
"key" => 'string',
|
||||
|
||||
@@ -4,9 +4,19 @@ namespace App\Models;
|
||||
|
||||
class GithubApp extends BaseModel
|
||||
{
|
||||
protected $fillable = ['name', 'uuid', 'organization', 'api_url', 'html_url', 'custom_user', 'custom_port', 'team_id'];
|
||||
protected $casts = [
|
||||
'is_public' => 'boolean',
|
||||
];
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::deleting(function (GithubApp $github_app) {
|
||||
$applications_count = Application::where('source_id', $github_app->id)->count();
|
||||
if ($applications_count > 0) {
|
||||
throw new \Exception('You cannot delete this GitHub App because it is in use by ' . $applications_count . ' application(s). Delete them first.');
|
||||
}
|
||||
});
|
||||
}
|
||||
public function applications()
|
||||
{
|
||||
return $this->morphMany(Application::class, 'source');
|
||||
@@ -15,4 +25,12 @@ class GithubApp extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(PrivateKey::class);
|
||||
}
|
||||
static public function public()
|
||||
{
|
||||
return GithubApp::where('team_id', session('currentTeam')->id)->where('is_public', true)->get();
|
||||
}
|
||||
static public function private()
|
||||
{
|
||||
return GithubApp::where('team_id', session('currentTeam')->id)->where('is_public', false)->get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ class Server extends BaseModel
|
||||
'extra_attributes' => SchemalessAttributes::class,
|
||||
];
|
||||
|
||||
|
||||
public function standaloneDockers()
|
||||
{
|
||||
return $this->hasMany(StandaloneDocker::class);
|
||||
@@ -52,4 +53,27 @@ class Server extends BaseModel
|
||||
{
|
||||
return $this->hasOne(ServerSetting::class);
|
||||
}
|
||||
|
||||
static public function validated()
|
||||
{
|
||||
return Server::where('team_id', session('currentTeam')->id)->whereRelation('settings', 'is_validated', true)->get();
|
||||
}
|
||||
static public function destinations(string|null $server_uuid = null)
|
||||
{
|
||||
if ($server_uuid) {
|
||||
$server = Server::where('team_id', session('currentTeam')->id)->where('uuid', $server_uuid)->firstOrFail();
|
||||
$standaloneDocker = collect($server->standaloneDockers->all());
|
||||
$swarmDocker = collect($server->swarmDockers->all());
|
||||
return $standaloneDocker->concat($swarmDocker);
|
||||
} else {
|
||||
$servers = Server::where('team_id', session('currentTeam')->id)->get();
|
||||
$standaloneDocker = $servers->map(function ($server) {
|
||||
return $server->standaloneDockers;
|
||||
})->flatten();
|
||||
$swarmDocker = $servers->map(function ($server) {
|
||||
return $server->swarmDockers;
|
||||
})->flatten();
|
||||
return $standaloneDocker->concat($swarmDocker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,4 +74,10 @@ class User extends Authenticatable
|
||||
return $team->id != $team_id;
|
||||
});
|
||||
}
|
||||
public function resources()
|
||||
{
|
||||
$team_id = data_get(session('currentTeam'), 'id');
|
||||
$data = Application::where('team_id', $team_id)->get();
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
// if (config('app.env') === 'production' && Str::contains(config('coolify.version'), ['nightly'])) {
|
||||
// if (config('app.env') === 'production' && Str::contains(config('version'), ['nightly'])) {
|
||||
// Process::run('php artisan migrate:fresh --force --seed --seeder=ProductionSeeder');
|
||||
// }
|
||||
}
|
||||
|
||||
41
app/Providers/HorizonServiceProvider.php
Normal file
41
app/Providers/HorizonServiceProvider.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Laravel\Horizon\Horizon;
|
||||
use Laravel\Horizon\HorizonApplicationServiceProvider;
|
||||
|
||||
class HorizonServiceProvider extends HorizonApplicationServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
|
||||
// Horizon::routeSmsNotificationsTo('15556667777');
|
||||
// Horizon::routeMailNotificationsTo('example@example.com');
|
||||
// Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
|
||||
|
||||
Horizon::night();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Horizon gate.
|
||||
*
|
||||
* This gate determines who can access Horizon in non-local environments.
|
||||
*/
|
||||
protected function gate(): void
|
||||
{
|
||||
Gate::define('viewHorizon', function ($user) {
|
||||
$root_user = User::find(0);
|
||||
return in_array($user->email, [
|
||||
$root_user->email
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,9 @@ class RouteServiceProvider extends ServiceProvider
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::prefix('webhooks')
|
||||
->group(base_path('routes/webhooks.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user