From e3e8fe789507a9eefbfa00db43359fcc6234b5e2 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 16 Feb 2024 01:56:16 +0300 Subject: [PATCH 01/13] =?UTF-8?q?=F0=9F=91=8C=20IMPORVE(SCRIPT/INSTALL):?= =?UTF-8?q?=20Support=20Archlinux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/install.sh | 87 +++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index a92755107..42b0c24e6 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -11,7 +11,13 @@ DOCKER_VERSION="24.0" CDN="https://cdn.coollabs.io/coolify" OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') -OS_VERSION=$(grep -w "VERSION_ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') + +if [ "$OS_TYPE" = "arch" ]; then + OS_VERSION="rolling" +else + OS_VERSION=$(grep -w "VERSION_ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"') +fi + LATEST_VERSION=$(curl --silent $CDN/versions.json | grep -i version | sed -n '2p' | xargs | awk '{print $2}' | tr -d ',') DATE=$(date +"%Y%m%d-%H%M%S") @@ -21,11 +27,11 @@ if [ $EUID != 0 ]; then fi case "$OS_TYPE" in -ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed) ;; -*) - echo "This script only supports Debian, Redhat or Sles based operating systems for now." - exit - ;; + arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed) ;; + *) + echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now." + exit + ;; esac # Overwrite LATEST_VERSION if user pass a version number @@ -48,21 +54,27 @@ echo -e "-------------" echo "Installing required packages..." case "$OS_TYPE" in -ubuntu | debian | raspbian) - apt update -y >/dev/null 2>&1 - apt install -y curl wget git jq >/dev/null 2>&1 - ;; -centos | fedora | rhel | ol | rocky) - dnf install -y curl wget git jq >/dev/null 2>&1 - ;; -sles | opensuse-leap | opensuse-tumbleweed) - zypper refresh >/dev/null 2>&1 - zypper install -y curl wget git jq >/dev/null 2>&1 - ;; -*) - echo "This script only supports Debian, Redhat or Sles based operating systems for now." - exit - ;; + arch) + pacman -Sy >/dev/null 2>&1 || true + if ! pacman -Q curl wget git jq >/dev/null 2>&1; then + pacman -S --noconfirm curl wget git jq >/dev/null 2>&1 || true + fi + ;; + ubuntu | debian | raspbian) + apt update -y >/dev/null 2>&1 + apt install -y curl wget git jq >/dev/null 2>&1 + ;; + centos | fedora | rhel | ol | rocky) + dnf install -y curl wget git jq >/dev/null 2>&1 + ;; + sles | opensuse-leap | opensuse-tumbleweed) + zypper refresh >/dev/null 2>&1 + zypper install -y curl wget git jq >/dev/null 2>&1 + ;; + *) + echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now." + exit + ;; esac # Detect OpenSSH server @@ -105,22 +117,35 @@ fi if ! [ -x "$(command -v docker)" ]; then echo "Docker is not installed. Installing Docker." - curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh - if [ -x "$(command -v docker)" ]; then - echo "Docker installed successfully." - else - echo "Docker installation failed with Rancher script. Trying with official script." - curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION} + if [ "$OS_TYPE" = "arch" ]; then + pacman -Sy docker docker-compose --noconfirm + systemctl enable docker.service if [ -x "$(command -v docker)" ]; then echo "Docker installed successfully." else - echo "Docker installation failed with official script." - echo "Maybe your OS is not supported." - echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue." - exit 1 + echo "Failed to install Docker with Rancher script. Trying to install with AUR." + echo "Please visit https://wiki.archlinux.org/title/docker for more information." + exit + fi + else + curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh + if [ -x "$(command -v docker)" ]; then + echo "Docker installed successfully." + else + echo "Docker installation failed with Rancher script. Trying with official script." + curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION} + if [ -x "$(command -v docker)" ]; then + echo "Docker installed successfully." + else + echo "Docker installation failed with official script." + echo "Maybe your OS is not supported." + echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue." + exit 1 + fi fi fi fi + echo -e "-------------" echo -e "Check Docker Configuration..." mkdir -p /etc/docker From 83becdb19d465563fffea01a070660784f35531c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 16 Feb 2024 08:34:30 +0100 Subject: [PATCH 02/13] fix: only show redeployment required if status is not exited --- app/Models/Application.php | 3 +++ config/sentry.php | 2 +- config/version.php | 2 +- resources/views/livewire/project/application/general.blade.php | 2 +- versions.json | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/Models/Application.php b/app/Models/Application.php index df1fb8038..a12be33fd 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -212,6 +212,9 @@ class Application extends BaseModel ); } + public function isExited() { + return (bool) str($this->status)->startsWith('exited'); + } public function realStatus() { return $this->getRawOriginal('status'); diff --git a/config/sentry.php b/config/sentry.php index 80b7ffe7f..bc708e23e 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.219', + 'release' => '4.0.0-beta.220', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 81f48a3c5..97edca729 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Save - @if ($isConfigurationChanged && !is_null($application->config_hash)) + @if ($isConfigurationChanged && !is_null($application->config_hash) && !$application->isExited())
diff --git a/versions.json b/versions.json index da42b0e85..86af46b94 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.219" + "version": "4.0.0-beta.220" } } } From 5fdadcf557c9bb418a7f5fe2cc7491e48741822d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 16 Feb 2024 09:04:32 +0100 Subject: [PATCH 03/13] fix: add openbsd ssh server check --- scripts/install.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 42b0c24e6..1293f98de 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -81,12 +81,20 @@ esac SSH_DETECTED=false if [ -x "$(command -v systemctl)" ]; then if systemctl status sshd >/dev/null 2>&1; then - echo "OpenSSH server is installed and running." + echo "OpenSSH server is installed." + SSH_DETECTED=true + fi + if systemctl status ssh >/dev/null 2>&1; then + echo "OpenSSH server is installed." SSH_DETECTED=true fi elif [ -x "$(command -v service)" ]; then if service sshd status >/dev/null 2>&1; then - echo "OpenSSH server is installed and running." + echo "OpenSSH server is installed." + SSH_DETECTED=true + fi + if service ssh status >/dev/null 2>&1; then + echo "OpenSSH server is installed." SSH_DETECTED=true fi fi From 3539e4dce95673978be9c0697bd0aa8c64aff56d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 16 Feb 2024 09:06:28 +0100 Subject: [PATCH 04/13] Update Docker installation error messages --- scripts/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 1293f98de..0ce06e0cf 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -131,7 +131,7 @@ if ! [ -x "$(command -v docker)" ]; then if [ -x "$(command -v docker)" ]; then echo "Docker installed successfully." else - echo "Failed to install Docker with Rancher script. Trying to install with AUR." + echo "Failed to install Docker with pacman. Try to install it manually." echo "Please visit https://wiki.archlinux.org/title/docker for more information." exit fi @@ -146,7 +146,7 @@ if ! [ -x "$(command -v docker)" ]; then echo "Docker installed successfully." else echo "Docker installation failed with official script." - echo "Maybe your OS is not supported." + echo "Maybe your OS is not supported?" echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue." exit 1 fi From b8708f086e9b09a4bda2441453853787729b735b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 16 Feb 2024 21:56:38 +0100 Subject: [PATCH 05/13] feat: initial api endpoints feat: server resources are now looks better --- app/Http/Controllers/Api/Deploy.php | 3 +- app/Http/Controllers/Api/Project.php | 39 ++++++++ app/Http/Controllers/Api/Server.php | 54 +++++++++++ app/Livewire/Project/Resource/Index.php | 2 +- app/Livewire/Server/Resources.php | 30 ++++++ app/Models/Environment.php | 1 - app/Models/ProjectSetting.php | 9 +- app/Models/Server.php | 2 + app/Models/Service.php | 42 +++++++++ app/Models/StandaloneMariadb.php | 3 + app/Models/StandaloneMongodb.php | 3 + app/Models/StandaloneMysql.php | 3 + app/Models/StandalonePostgresql.php | 4 + app/Models/StandaloneRedis.php | 4 + app/View/Components/Status/Services.php | 2 +- bootstrap/helpers/api.php | 7 ++ bootstrap/helpers/services.php | 43 --------- .../views/components/server/navbar.blade.php | 6 ++ .../components/services/navbar.blade.php | 6 +- .../views/components/status/index.blade.php | 10 +- .../views/livewire/server/delete.blade.php | 42 ++++----- .../views/livewire/server/resources.blade.php | 46 +++++++++ routes/api.php | 94 +++++++------------ routes/web.php | 5 +- 24 files changed, 318 insertions(+), 142 deletions(-) create mode 100644 app/Http/Controllers/Api/Project.php create mode 100644 app/Http/Controllers/Api/Server.php create mode 100644 app/Livewire/Server/Resources.php create mode 100644 bootstrap/helpers/api.php create mode 100644 resources/views/livewire/server/resources.blade.php diff --git a/app/Http/Controllers/Api/Deploy.php b/app/Http/Controllers/Api/Deploy.php index f071f3b5b..21da51d66 100644 --- a/app/Http/Controllers/Api/Deploy.php +++ b/app/Http/Controllers/Api/Deploy.php @@ -18,8 +18,7 @@ class Deploy extends Controller { public function deploy(Request $request) { - $token = auth()->user()->currentAccessToken(); - $teamId = data_get($token, 'team_id'); + $teamId = get_team_id_from_token(); $uuids = $request->query->get('uuid'); $tags = $request->query->get('tag'); $force = $request->query->get('force') ?? false; diff --git a/app/Http/Controllers/Api/Project.php b/app/Http/Controllers/Api/Project.php new file mode 100644 index 000000000..fa2ba34bb --- /dev/null +++ b/app/Http/Controllers/Api/Project.php @@ -0,0 +1,39 @@ +json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $projects = ModelsProject::whereTeamId($teamId)->select('id', 'name', 'uuid')->get(); + return response()->json($projects); + } + public function project_by_uuid(Request $request) + { + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $project = ModelsProject::whereTeamId($teamId)->whereUuid(request()->uuid)->first()->load(['environments']); + return response()->json($project); + } + public function environment_details(Request $request) + { + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $project = ModelsProject::whereTeamId($teamId)->whereUuid(request()->uuid)->first(); + $environment = $project->environments()->whereName(request()->environment_name)->first()->load(['applications', 'postgresqls', 'redis', 'mongodbs', 'mysqls', 'mariadbs', 'services']); + return response()->json($environment); + } +} diff --git a/app/Http/Controllers/Api/Server.php b/app/Http/Controllers/Api/Server.php new file mode 100644 index 000000000..e7b071a43 --- /dev/null +++ b/app/Http/Controllers/Api/Server.php @@ -0,0 +1,54 @@ +json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $servers = ModelsServer::whereTeamId($teamId)->select('id', 'name', 'uuid', 'ip', 'user', 'port')->get()->load(['settings'])->map(function ($server) { + $server['is_reachable'] = $server->settings->is_reachable; + $server['is_usable'] = $server->settings->is_usable; + return $server; + }); + ray($servers); + return response()->json($servers); + } + public function server_by_uuid(Request $request) + { + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $server = ModelsServer::whereTeamId($teamId)->whereUuid(request()->uuid)->first(); + if (is_null($server)) { + return response()->json(['error' => 'Server not found.'], 404); + } + $server->load(['settings']); + $server['resources'] = $server->definedResources()->map(function ($resource) { + $payload = [ + 'id' => $resource->id, + 'uuid' => $resource->uuid, + 'name' => $resource->name, + 'type' => $resource->type(), + 'created_at' => $resource->created_at, + 'updated_at' => $resource->updated_at, + ]; + if ($resource->type() === 'service') { + $payload['status'] = $resource->status(); + } else { + $payload['status'] = $resource->status; + } + return $payload; + }); + return response()->json($server); + } +} diff --git a/app/Livewire/Project/Resource/Index.php b/app/Livewire/Project/Resource/Index.php index 9e0a5e9db..9524392dc 100644 --- a/app/Livewire/Project/Resource/Index.php +++ b/app/Livewire/Project/Resource/Index.php @@ -104,7 +104,7 @@ class Index extends Component 'environment_name' => data_get($service, 'environment.name'), 'service_uuid' => data_get($service, 'uuid') ]); - $service->status = serviceStatus($service); + $service->status = $service->status(); } return $service; }); diff --git a/app/Livewire/Server/Resources.php b/app/Livewire/Server/Resources.php new file mode 100644 index 000000000..f9f3af37c --- /dev/null +++ b/app/Livewire/Server/Resources.php @@ -0,0 +1,30 @@ +parameters = get_route_parameters(); + try { + $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); + if (is_null($this->server)) { + return redirect()->route('server.index'); + } + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function render() + { + return view('livewire.server.resources'); + } +} diff --git a/app/Models/Environment.php b/app/Models/Environment.php index b9451ac3f..efbfc70d9 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -26,7 +26,6 @@ class Environment extends Model { return $this->hasMany(Application::class); } - public function postgresqls() { return $this->hasMany(StandalonePostgresql::class); diff --git a/app/Models/ProjectSetting.php b/app/Models/ProjectSetting.php index 50192099e..d93bea05b 100644 --- a/app/Models/ProjectSetting.php +++ b/app/Models/ProjectSetting.php @@ -6,7 +6,10 @@ use Illuminate\Database\Eloquent\Model; class ProjectSetting extends Model { - protected $fillable = [ - 'project_id' - ]; + protected $guarded = []; + + public function project() + { + return $this->belongsTo(Project::class); + } } diff --git a/app/Models/Server.php b/app/Models/Server.php index f19943d05..ce34486ed 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -245,6 +245,8 @@ class Server extends BaseModel $mysqls = data_get($standaloneDocker, 'mysqls', collect([])); $mariadbs = data_get($standaloneDocker, 'mariadbs', collect([])); return $postgresqls->concat($redis)->concat($mongodbs)->concat($mysqls)->concat($mariadbs); + })->filter(function ($item) { + return data_get($item,'name') === 'coolify-db'; })->flatten(); } public function applications() diff --git a/app/Models/Service.php b/app/Models/Service.php index 244964db1..246e812c2 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -28,6 +28,48 @@ class Service extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function status() { + $foundRunning = false; + $isDegraded = false; + $foundRestaring = false; + $applications = $this->applications; + $databases = $this->databases; + foreach ($applications as $application) { + if ($application->exclude_from_status) { + continue; + } + if (Str::of($application->status)->startsWith('running')) { + $foundRunning = true; + } else if (Str::of($application->status)->startsWith('restarting')) { + $foundRestaring = true; + } else { + $isDegraded = true; + } + } + foreach ($databases as $database) { + if ($database->exclude_from_status) { + continue; + } + if (Str::of($database->status)->startsWith('running')) { + $foundRunning = true; + } else if (Str::of($database->status)->startsWith('restarting')) { + $foundRestaring = true; + } else { + $isDegraded = true; + } + } + if ($foundRestaring) { + return 'degraded'; + } + if ($foundRunning && !$isDegraded) { + return 'running'; + } else if ($foundRunning && $isDegraded) { + return 'degraded'; + } else if (!$foundRunning && !$isDegraded) { + return 'exited'; + } + return 'exited'; + } public function extraFields() { $fields = collect([]); diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index 1143b018e..174397baa 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -82,6 +82,9 @@ class StandaloneMariadb extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 610323f74..d6efaaa1e 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -85,6 +85,9 @@ class StandaloneMongodb extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index fa6bbe28f..f317196aa 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -82,6 +82,9 @@ class StandaloneMysql extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index bcc43843b..3d2317159 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -82,6 +82,10 @@ class StandalonePostgresql extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() + { + return data_get($this, 'environment.project'); + } public function link() { if (data_get($this, 'environment.project.uuid')) { diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 59c53f882..6b6b6c415 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -77,6 +77,10 @@ class StandaloneRedis extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() + { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/View/Components/Status/Services.php b/app/View/Components/Status/Services.php index 3fc302acf..f81ca9703 100644 --- a/app/View/Components/Status/Services.php +++ b/app/View/Components/Status/Services.php @@ -16,7 +16,7 @@ class Services extends Component public Service $service, public string $complexStatus = 'exited', ) { - $this->complexStatus = serviceStatus($service); + $this->complexStatus = $service->status(); } /** diff --git a/bootstrap/helpers/api.php b/bootstrap/helpers/api.php new file mode 100644 index 000000000..94e9242cb --- /dev/null +++ b/bootstrap/helpers/api.php @@ -0,0 +1,7 @@ +user()->currentAccessToken(); + return data_get($token, 'team_id'); +} diff --git a/bootstrap/helpers/services.php b/bootstrap/helpers/services.php index 43a15444c..aa7d6fd54 100644 --- a/bootstrap/helpers/services.php +++ b/bootstrap/helpers/services.php @@ -21,49 +21,6 @@ function replaceVariables($variable) return $variable->replaceFirst('$', '')->replaceFirst('{', '')->replaceLast('}', ''); } -function serviceStatus(Service $service) -{ - $foundRunning = false; - $isDegraded = false; - $foundRestaring = false; - $applications = $service->applications; - $databases = $service->databases; - foreach ($applications as $application) { - if ($application->exclude_from_status) { - continue; - } - if (Str::of($application->status)->startsWith('running')) { - $foundRunning = true; - } else if (Str::of($application->status)->startsWith('restarting')) { - $foundRestaring = true; - } else { - $isDegraded = true; - } - } - foreach ($databases as $database) { - if ($database->exclude_from_status) { - continue; - } - if (Str::of($database->status)->startsWith('running')) { - $foundRunning = true; - } else if (Str::of($database->status)->startsWith('restarting')) { - $foundRestaring = true; - } else { - $isDegraded = true; - } - } - if ($foundRestaring) { - return 'degraded'; - } - if ($foundRunning && !$isDegraded) { - return 'running'; - } else if ($foundRunning && $isDegraded) { - return 'degraded'; - } else if (!$foundRunning && !$isDegraded) { - return 'exited'; - } - return 'exited'; -} function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneService, bool $isInit = false) { // TODO: make this async diff --git a/resources/views/components/server/navbar.blade.php b/resources/views/components/server/navbar.blade.php index a6a2dd74a..08a8019a8 100644 --- a/resources/views/components/server/navbar.blade.php +++ b/resources/views/components/server/navbar.blade.php @@ -18,6 +18,12 @@ ]) }}"> + + +
- @if (serviceStatus($service) === 'degraded') + @if ($service->status() === 'degraded') @endif - @if (serviceStatus($service) === 'running') + @if ($service->status() === 'running')