From 62ae845f4b0d0607bf2b30b936d59f3cd2029f5b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 23 Feb 2024 10:09:42 +0100 Subject: [PATCH] fix: complex service status service: firefly III --- app/Models/Service.php | 79 ++++++++++++------- public/svgs/firefly.svg | 21 +++++ .../components/services/navbar.blade.php | 21 +++-- .../components/status/degraded.blade.php | 9 ++- .../components/status/restarting.blade.php | 2 +- .../livewire/project/new/select.blade.php | 2 +- templates/compose/appsmith.yaml | 4 +- templates/compose/firefly.yaml | 56 +++++++++++++ templates/service-templates.json | 15 +++- 9 files changed, 164 insertions(+), 45 deletions(-) create mode 100644 public/svgs/firefly.svg create mode 100644 templates/compose/firefly.yaml diff --git a/app/Models/Service.php b/app/Models/Service.php index 246e812c2..9fa175bae 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -6,7 +6,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Collection; -use Illuminate\Support\Str; class Service extends BaseModel { @@ -28,47 +27,73 @@ class Service extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } - public function status() { - $foundRunning = false; - $isDegraded = false; - $foundRestaring = false; + public function status() + { $applications = $this->applications; $databases = $this->databases; + + $complexStatus = null; + $complexHealth = null; + 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; + $status = str($application->status)->before('(')->trim(); + $health = str($application->status)->between('(', ')')->trim(); + if ($complexStatus === 'degraded') { + continue; + } + if ($status->startsWith('running')) { + if ($complexStatus === 'exited') { + $complexStatus = 'degraded'; + } else { + $complexStatus = 'running'; + } + } else if ($status->startsWith('restarting')) { + $complexStatus = 'degraded'; + } else if ($status->startsWith('exited')) { + $complexStatus = 'exited'; + } + if ($health->value() === 'healthy') { + if ($complexHealth === 'unhealthy') { + continue; + } + $complexHealth = 'healthy'; } else { - $isDegraded = true; + $complexHealth = 'unhealthy'; } } 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; + $status = str($database->status)->before('(')->trim(); + $health = str($database->status)->between('(', ')')->trim(); + if ($complexStatus === 'degraded') { + continue; + } + if ($status->startsWith('running')) { + if ($complexStatus === 'exited') { + $complexStatus = 'degraded'; + } else { + $complexStatus = 'running'; + } + } else if ($status->startsWith('restarting')) { + $complexStatus = 'degraded'; + } else if ($status->startsWith('exited')) { + $complexStatus = 'exited'; + } + if ($health->value() === 'healthy') { + if ($complexHealth === 'unhealthy') { + continue; + } + $complexHealth = 'healthy'; } else { - $isDegraded = true; + $complexHealth = 'unhealthy'; } } - if ($foundRestaring) { - return 'degraded'; - } - if ($foundRunning && !$isDegraded) { - return 'running'; - } else if ($foundRunning && $isDegraded) { - return 'degraded'; - } else if (!$foundRunning && !$isDegraded) { - return 'exited'; - } - return 'exited'; + return "{$complexStatus}:{$complexHealth}"; } public function extraFields() { @@ -414,7 +439,7 @@ class Service extends BaseModel public function documentation() { $services = getServiceTemplates(); - $service = data_get($services, Str::of($this->name)->beforeLast('-')->value, []); + $service = data_get($services, str($this->name)->beforeLast('-')->value, []); return data_get($service, 'documentation', config('constants.docs.base_url')); } public function applications() diff --git a/public/svgs/firefly.svg b/public/svgs/firefly.svg new file mode 100644 index 000000000..cd371be1b --- /dev/null +++ b/public/svgs/firefly.svg @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/resources/views/components/services/navbar.blade.php b/resources/views/components/services/navbar.blade.php index e5327935f..e593b79a8 100644 --- a/resources/views/components/services/navbar.blade.php +++ b/resources/views/components/services/navbar.blade.php @@ -1,11 +1,11 @@ @script - + @endscript diff --git a/resources/views/components/status/degraded.blade.php b/resources/views/components/status/degraded.blade.php index 81beedfa7..490ecc239 100644 --- a/resources/views/components/status/degraded.blade.php +++ b/resources/views/components/status/degraded.blade.php @@ -2,7 +2,12 @@ 'status' => 'Degraded', ]) -
+
-
{{ Str::headline($status) }}
+
+ {{ str($status)->before(':')->headline() }} +
+ @if (!str($status)->startsWith('Proxy') && !str($status)->contains('(')) +
({{ str($status)->after(':') }})
+ @endif
diff --git a/resources/views/components/status/restarting.blade.php b/resources/views/components/status/restarting.blade.php index 50142de1a..d9c353d02 100644 --- a/resources/views/components/status/restarting.blade.php +++ b/resources/views/components/status/restarting.blade.php @@ -2,7 +2,7 @@ 'status' => 'Restarting', ]) -
+
{{ str($status)->before(':')->headline() }} diff --git a/resources/views/livewire/project/new/select.blade.php b/resources/views/livewire/project/new/select.blade.php index 4ae372871..0f63e2605 100644 --- a/resources/views/livewire/project/new/select.blade.php +++ b/resources/views/livewire/project/new/select.blade.php @@ -168,7 +168,7 @@ Reload List + wire:model.live.debounce.200ms="search" autofocus placeholder="Search...">
@if ($loadingServices) diff --git a/templates/compose/appsmith.yaml b/templates/compose/appsmith.yaml index 65861db9f..a70c5ba90 100644 --- a/templates/compose/appsmith.yaml +++ b/templates/compose/appsmith.yaml @@ -7,11 +7,11 @@ services: appsmith: image: index.docker.io/appsmith/appsmith-ce:latest environment: - - SERVICE_FQDN + - SERVICE_FQDN_APPSMITH - APPSMITH_MAIL_ENABLED=false - APPSMITH_DISABLE_TELEMETRY=true - APPSMITH_DISABLE_INTERCOM=true - - APPSMITH_SENTRY_DSN= + - APPSMITH_SENTRY_DSN= - APPSMITH_SMART_LOOK_ID= volumes: - stacks-data:/appsmith-stacks diff --git a/templates/compose/firefly.yaml b/templates/compose/firefly.yaml new file mode 100644 index 000000000..49dc0d9cf --- /dev/null +++ b/templates/compose/firefly.yaml @@ -0,0 +1,56 @@ +# documentation: https://firefly-iii.org +# slogan: A personal finances manager that can help you save money. +# tags: finance, money, personal, manager +# logo: svgs/firefly.svg + +services: + firefly: + image: fireflyiii/core:latest + environment: + - SERVICE_FQDN_FIREFLY + - APP_KEY=$SERVICE_BASE64_APPKEY + - DB_HOST=mysql + - DB_PORT=3306 + - DB_CONNECTION=mysql + - DB_DATABASE=${MYSQL_DATABASE:-firefly} + - DB_USERNAME=$SERVICE_USER_MYSQL + - DB_PASSWORD=$SERVICE_PASSWORD_MYSQL + - STATIC_CRON_TOKEN=$SERVICE_BASE64_CRONTOKEN + volumes: + - firefly-upload:/var/www/html/storage/upload + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080"] + interval: 5s + timeout: 20s + retries: 10 + depends_on: + mysql: + condition: service_healthy + mysql: + image: mariadb:lts + environment: + - MYSQL_USER=${SERVICE_USER_MYSQL} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} + - MYSQL_DATABASE=${MYSQL_DATABASE:-firefly} + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT} + healthcheck: + test: + [ + "CMD", + "mysqladmin", + "ping", + "-h", + "localhost", + "-uroot", + "-p${SERVICE_PASSWORD_MYSQLROOT}", + ] + interval: 5s + timeout: 20s + retries: 10 + volumes: + - firefly-mysql-data:/var/lib/mysql + # cron: + # image: alpine + # command: sh -c "echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/$STATIC_CRON_TOKEN\" | crontab - && crond -f -L /dev/stdout" + # environment: + # - STATIC_CRON_TOKEN=$SERVICE_PASSWORD_32_CRONTOKEN diff --git a/templates/service-templates.json b/templates/service-templates.json index db7654401..50b53a7f1 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -2,7 +2,7 @@ "appsmith": { "documentation": "https:\/\/appsmith.com", "slogan": "Appsmith is low-code application platform for building internal tools.", - "compose": "c2VydmljZXM6CiAgYXBwc21pdGg6CiAgICBpbWFnZTogJ2luZGV4LmRvY2tlci5pby9hcHBzbWl0aC9hcHBzbWl0aC1jZTpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE4KICAgICAgLSBBUFBTTUlUSF9NQUlMX0VOQUJMRUQ9ZmFsc2UKICAgICAgLSBBUFBTTUlUSF9ESVNBQkxFX1RFTEVNRVRSWT10cnVlCiAgICAgIC0gQVBQU01JVEhfRElTQUJMRV9JTlRFUkNPTT10cnVlCiAgICAgIC0gQVBQU01JVEhfU0VOVFJZX0RTTj0KICAgICAgLSBBUFBTTUlUSF9TTUFSVF9MT09LX0lEPQogICAgdm9sdW1lczoKICAgICAgLSAnc3RhY2tzLWRhdGE6L2FwcHNtaXRoLXN0YWNrcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gTk9ORQo=", + "compose": "c2VydmljZXM6CiAgYXBwc21pdGg6CiAgICBpbWFnZTogJ2luZGV4LmRvY2tlci5pby9hcHBzbWl0aC9hcHBzbWl0aC1jZTpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVBQU01JVEgKICAgICAgLSBBUFBTTUlUSF9NQUlMX0VOQUJMRUQ9ZmFsc2UKICAgICAgLSBBUFBTTUlUSF9ESVNBQkxFX1RFTEVNRVRSWT10cnVlCiAgICAgIC0gQVBQU01JVEhfRElTQUJMRV9JTlRFUkNPTT10cnVlCiAgICAgIC0gQVBQU01JVEhfU0VOVFJZX0RTTj0KICAgICAgLSBBUFBTTUlUSF9TTUFSVF9MT09LX0lEPQogICAgdm9sdW1lczoKICAgICAgLSAnc3RhY2tzLWRhdGE6L2FwcHNtaXRoLXN0YWNrcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gTk9ORQo=", "tags": [ "lowcode", "nocode", @@ -192,6 +192,19 @@ "logo": "svgs\/filebrowser.svg", "minversion": "0.0.0" }, + "firefly": { + "documentation": "https:\/\/firefly-iii.org", + "slogan": "A personal finances manager that can help you save money.", + "compose": "c2VydmljZXM6CiAgZmlyZWZseToKICAgIGltYWdlOiAnZmlyZWZseWlpaS9jb3JlOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GSVJFRkxZCiAgICAgIC0gQVBQX0tFWT0kU0VSVklDRV9CQVNFNjRfQVBQS0VZCiAgICAgIC0gREJfSE9TVD1teXNxbAogICAgICAtIERCX1BPUlQ9MzMwNgogICAgICAtIERCX0NPTk5FQ1RJT049bXlzcWwKICAgICAgLSAnREJfREFUQUJBU0U9JHtNWVNRTF9EQVRBQkFTRTotZmlyZWZseX0nCiAgICAgIC0gREJfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9NWVNRTAogICAgICAtIERCX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01ZU1FMCiAgICAgIC0gU1RBVElDX0NST05fVE9LRU49JFNFUlZJQ0VfQkFTRTY0X0NST05UT0tFTgogICAgdm9sdW1lczoKICAgICAgLSAnZmlyZWZseS11cGxvYWQ6L3Zhci93d3cvaHRtbC9zdG9yYWdlL3VwbG9hZCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDgwJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBteXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIG15c3FsOgogICAgaW1hZ2U6ICdtYXJpYWRiOmx0cycKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01ZU1FMfScKICAgICAgLSAnTVlTUUxfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMfScKICAgICAgLSAnTVlTUUxfREFUQUJBU0U9JHtNWVNRTF9EQVRBQkFTRTotZmlyZWZseX0nCiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMUk9PVH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbXlzcWxhZG1pbgogICAgICAgIC0gcGluZwogICAgICAgIC0gJy1oJwogICAgICAgIC0gbG9jYWxob3N0CiAgICAgICAgLSAnLXVyb290JwogICAgICAgIC0gJy1wJHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMUk9PVH0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZpcmVmbHktbXlzcWwtZGF0YTovdmFyL2xpYi9teXNxbCcK", + "tags": [ + "finance", + "money", + "personal", + "manager" + ], + "logo": "svgs\/firefly.svg", + "minversion": "0.0.0" + }, "formbricks": { "documentation": "https:\/\/formbricks.com", "slogan": "Open Source Experience Management",