Skip to content

Commit

Permalink
Merge branch 'main' into open-telemetry-tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
joshk authored Nov 14, 2024
2 parents 9c549fe + 80dd9e9 commit 6ee3e2f
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 25 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
tags:
- 'v*'
- "v*"
workflow_dispatch:
pull_request:

Expand All @@ -26,7 +26,7 @@ jobs:
services:
db:
image: postgres:15
ports: ['5432:5432']
ports: ["5432:5432"]
env:
POSTGRES_PASSWORD: postgres
options: >-
Expand Down Expand Up @@ -121,6 +121,8 @@ jobs:
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
env:
DOCKER_METADATA_PR_HEAD_SHA: true
with:
images: ghcr.io/nerves-hub/nerves-hub
tags: |
Expand All @@ -132,14 +134,15 @@ jobs:
type=raw,enable={{is_default_branch}},value=latest
# tag event (eg. "v1.2.3")
type=ref,event=tag
- name: Check if PR publish
continue-on-error: true
if: ${{ github.event_name == 'pull_request' }}
id: pr_publish_check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
commits=$(gh pr view ${{ github.head_ref }} --json commits --jq '.commits[] | .messageHeadline + " " + .messageBody')
commits=$(gh pr view ${{ github.event.pull_request.number }} --json commits --jq '.commits[] | .messageHeadline + " " + .messageBody')
if [[ $commits =~ \[publish\] ]]; then
echo "true"
Expand Down
34 changes: 28 additions & 6 deletions assets/css/_custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@
right: 0;
margin: auto;
z-index: 999;
// text-align: center;
}

.alarms-banner {
display: flex;
flex-direction: row;
justify-content: right;
padding-top: 2px;
padding-bottom: 2px;
}

.alarms-banner a {
color: #f78080;
}

.opacity-1 {
Expand Down Expand Up @@ -244,19 +255,28 @@
}
}

.device-limit-indicator {
background-image: url("/images/icons/device.svg");
background-position: right center;
.navbar-indicator {
background-position: left center;
background-repeat: no-repeat;
background-size: 1.5rem;
padding-right: 2rem;
letter-spacing: 4px;
padding-left: 1.8rem;
letter-spacing: 2px;

@media(max-width: 860px) {
display: none;
}
}

.device-limit-indicator {
background-image: url("/images/icons/device.svg");
}

.alarms-indicator {
background-image: url("/images/icons/bell.svg");
margin-left: 1.3rem;
font-weight: 400;
}

html {
.btn-group>form:not(:first-child) .btn {
margin-left: -1px;
Expand Down Expand Up @@ -345,6 +365,7 @@ html {
cursor: pointer;
display: flex;
gap: 4px;

label {
font-size: 14px;
border-radius: 3.2px;
Expand All @@ -360,6 +381,7 @@ html {
padding-right: 8px;
justify-content: center;
flex-grow: 1;

input[type=radio] {
appearance: none;
}
Expand Down
2 changes: 1 addition & 1 deletion assets/css/_form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ html {
.filter-form {
&.device-filters {
display: grid;
grid-template-columns: 3fr 3fr 3fr 2fr 2fr;
grid-template-columns: 2fr 2fr 2fr 2fr 3fr;
grid-column-gap: 1rem;

@media (max-width: 860px) {
Expand Down
5 changes: 5 additions & 0 deletions assets/static/images/icons/bell.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions lib/nerves_hub/devices.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule NervesHub.Devices do
alias NervesHub.Deployments.Deployment
alias NervesHub.Deployments.Orchestrator
alias NervesHub.Devices.CACertificate
alias NervesHub.Devices.Alarms
alias NervesHub.Devices.Device
alias NervesHub.Devices.DeviceCertificate
alias NervesHub.Devices.DeviceHealth
Expand Down Expand Up @@ -163,6 +164,15 @@ defmodule NervesHub.Devices do
{_, ""} ->
query

{:alarm_status, "with"} ->
where(query, [d], d.id in subquery(Alarms.query_devices_with_alarms()))

{:alarm_status, "without"} ->
where(query, [d], d.id not in subquery(Alarms.query_devices_with_alarms()))

{:alarm, value} ->
where(query, [d], d.id in subquery(Alarms.query_devices_with_alarm(value)))

{:connection, _value} ->
where(query, [d], d.connection_status == ^String.to_atom(value))

Expand Down
90 changes: 90 additions & 0 deletions lib/nerves_hub/devices/alarms.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
defmodule NervesHub.Devices.Alarms do
import Ecto.Query
alias NervesHub.Repo
alias NervesHub.Devices.Device
alias NervesHub.Devices.DeviceHealth

@doc """
Selects device id:s for devices that has alarm(s) in it's latest health record.
Used when filtering devices.
"""
def query_devices_with_alarms() do
(lr in subquery(latest_row_query()))
|> from()
|> where([lr], lr.rn == 1)
|> where([lr], fragment("?->'alarms' != '{}'", lr.data))
|> join(:inner, [lr], d in Device, on: lr.device_id == d.id)
|> select([lr, o], o.id)
end

@doc """
Selects device id:s for devices that has provided alarm in it's latest health record.
Used when filtering devices.
"""
def query_devices_with_alarm(alarm) do
(lr in subquery(latest_row_query()))
|> from()
|> where([lr], lr.rn == 1)
|> where(
[lr],
fragment(
"EXISTS (SELECT 1 FROM jsonb_each_text(?) WHERE value ILIKE ?)",
lr.data,
^"%#{alarm}%"
)
)
|> join(:inner, [lr], d in Device, on: lr.device_id == d.id)
|> select([lr, o], o.id)
end

@doc """
Creates a list with all current alarm types for a product.
"""
def get_current_alarm_types(product_id) do
query_current_alarms(product_id)
|> Repo.all()
|> Enum.map(fn %{data: data} ->
Map.keys(data["alarms"])
end)
|> List.flatten()
|> Enum.uniq()
|> Enum.map(&String.trim_leading(&1, "Elixir."))
end

@doc """
Counts number of devices currently alarming, within a product.
"""
def current_alarms_count(product_id) do
product_id
|> query_current_alarms()
|> select([a], count(a))
|> Repo.one!()
end

@doc """
Selects latest health per device if alarms is populated and device belongs to product.
"""
def query_current_alarms(product_id) do
(lr in subquery(latest_row_query()))
|> from()
|> where([lr], lr.rn == 1)
|> where([lr], fragment("?->'alarms' != '{}'", lr.data))
|> where([lr], lr.device_id in subquery(device_product_query(product_id)))
end

defp latest_row_query() do
DeviceHealth
|> select([dh], %{
device_id: dh.device_id,
data: dh.data,
inserted_at: dh.inserted_at,
rn: row_number() |> over(partition_by: dh.device_id, order_by: [desc: dh.inserted_at])
})
end

defp device_product_query(product_id) do
Device
|> select([:id])
|> where(product_id: ^product_id)
end
end
14 changes: 8 additions & 6 deletions lib/nerves_hub_web/channels/device_channel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ defmodule NervesHubWeb.DeviceChannel do
end

def handle_in("fwup_progress", %{"value" => percent}, %{assigns: %{device: device}} = socket) do
device_internal_broadcast!(device, "fwup_progress", %{percent: percent})
device_internal_broadcast!(socket, device, "fwup_progress", %{percent: percent})

# if this is the first fwup we see, then mark it as an update attempt
if socket.assigns[:update_started?] do
Expand Down Expand Up @@ -370,9 +370,11 @@ defmodule NervesHubWeb.DeviceChannel do

{:ok, device} = Devices.update_device(device, %{connection_metadata: metadata})

device_internal_broadcast!(device, "location:updated", location)
socket = assign(socket, :device, device)

{:reply, :ok, assign(socket, :device, device)}
device_internal_broadcast!(socket, device, "location:updated", location)

{:reply, :ok, socket}
end

def handle_in("connection_types", %{"values" => types}, %{assigns: %{device: device}} = socket) do
Expand Down Expand Up @@ -434,7 +436,7 @@ defmodule NervesHubWeb.DeviceChannel do
{:health_report, Devices.save_device_health(device_health)},
{:metrics_report, {_, _}} <-
{:metrics_report, Metrics.save_metrics(socket.assigns.device.id, metrics)} do
device_internal_broadcast!(socket.assigns.device, "health_check_report", %{})
device_internal_broadcast!(socket, socket.assigns.device, "health_check_report", %{})
else
{:health_report, {:error, err}} ->
Logger.warning("Failed to save health check data: #{inspect(err)}")
Expand Down Expand Up @@ -513,9 +515,9 @@ defmodule NervesHubWeb.DeviceChannel do
Phoenix.PubSub.unsubscribe(NervesHub.PubSub, topic)
end

defp device_internal_broadcast!(device, event, payload) do
defp device_internal_broadcast!(socket, device, event, payload) do
topic = "device:#{device.identifier}:internal"
NervesHubWeb.DeviceEndpoint.broadcast_from!(self(), topic, event, payload)
socket.endpoint.broadcast_from!(self(), topic, event, payload)
end

defp maybe_send_public_keys(device, socket, params) do
Expand Down
20 changes: 18 additions & 2 deletions lib/nerves_hub_web/components/navigation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule NervesHubWeb.Components.Navigation do
use NervesHubWeb, :component

alias NervesHub.Devices
alias NervesHub.Devices.Alarms
alias NervesHub.Products.Product

import NervesHubWeb.Components.SimpleActiveLink
Expand Down Expand Up @@ -115,6 +116,7 @@ defmodule NervesHubWeb.Components.Navigation do

if Enum.any?(links) do
assigns = %{
org: assigns.org,
product: assigns.product,
links: links
}
Expand All @@ -129,8 +131,19 @@ defmodule NervesHubWeb.Components.Navigation do
</.link>
</li>
</ul>
<div :if={device_count = device_count(@product)} class="device-limit-indicator" title="Device total" aria-label="Device total">
<%= device_count %>
<div class="flex-row align-items-center justify-content-between">
<div :if={device_count = device_count(@product)} class="navbar-indicator device-limit-indicator" title="Device total" aria-label="Device total">
<%= device_count %>
</div>
<.link
:if={alarms_count = alarms_count(@product)}
navigate={~p"/org/#{@org.name}/#{@product.name}/devices?alarm_status=with"}
class="navbar-indicator alarms-indicator"
title="Devices alarming"
aria-label="Devices alarming"
>
<%= alarms_count %>
</.link>
</div>
</nav>
</div>
Expand Down Expand Up @@ -308,4 +321,7 @@ defmodule NervesHubWeb.Components.Navigation do
def device_count(_conn) do
nil
end

def alarms_count(%Product{} = product), do: Alarms.current_alarms_count(product.id)
def alarms_count(_conn), do: nil
end
10 changes: 8 additions & 2 deletions lib/nerves_hub_web/live/devices/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule NervesHubWeb.Live.Devices.Index do

alias NervesHub.AuditLogs
alias NervesHub.Devices
alias NervesHub.Devices.Alarms
alias NervesHub.Firmwares
alias NervesHub.Products.Product
alias NervesHub.Tracker
Expand All @@ -29,7 +30,9 @@ defmodule NervesHubWeb.Live.Devices.Index do
device_id: "",
tag: "",
updates: "",
has_no_tags: false
has_no_tags: false,
alarm_status: "",
alarm: ""
}

@filter_types %{
Expand All @@ -41,7 +44,9 @@ defmodule NervesHubWeb.Live.Devices.Index do
device_id: :string,
tag: :string,
updates: :string,
has_no_tags: :boolean
has_no_tags: :boolean,
alarm_status: :string,
alarm: :string
}

@default_page 1
Expand Down Expand Up @@ -79,6 +84,7 @@ defmodule NervesHubWeb.Live.Devices.Index do
|> assign(:valid_tags, true)
|> assign(:device_tags, "")
|> assign(:total_entries, 0)
|> assign(:current_alarms, Alarms.get_current_alarm_types(product.id))
|> subscribe_and_refresh_device_list_timer()
|> ok()
end
Expand Down
Loading

0 comments on commit 6ee3e2f

Please sign in to comment.