Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Managed Deployments: Groups and Releases #1653

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/nerves_hub/accounts/remove_account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule NervesHub.Accounts.RemoveAccount do
alias NervesHub.{
Accounts,
Firmwares,
Deployments.Deployment,
ManagedDeployments.DeploymentGroup,
Products,
Repo,
OrgKey,
Expand All @@ -25,7 +25,7 @@ defmodule NervesHub.Accounts.RemoveAccount do
|> Multi.delete_all(:invites, &query_by_org_id(Invite, &1))
|> Multi.delete_all(:device_certificates, &query_by_org_id(DeviceCertificate, &1))
|> Multi.delete_all(:ca_certificates, &query_by_org_id(CACertificate, &1))
|> Multi.delete_all(:deployments, &query_by_org_id(Deployment, &1))
|> Multi.delete_all(:deployment_groups, &query_by_org_id(DeploymentGroup, &1))
|> Multi.delete_all(:firmware_deltas, &query_firmware_deltas/1)
|> Multi.delete_all(:firmware_transfers, &query_by_org_id(FirmwareTransfer, &1))
|> Multi.merge(&delete_firmwares/1)
Expand Down
2 changes: 1 addition & 1 deletion lib/nerves_hub/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ defmodule NervesHub.Application do
defp deployments_supervisor("test"), do: []

defp deployments_supervisor(_) do
[NervesHub.Deployments.Supervisor]
[NervesHub.ManagedDeployments.Supervisor]
end

defp endpoints("test") do
Expand Down
6 changes: 3 additions & 3 deletions lib/nerves_hub/audit_logs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule NervesHub.AuditLogs do
import Ecto.Query

alias NervesHub.AuditLogs.AuditLog
alias NervesHub.Deployments.Deployment
alias NervesHub.ManagedDeployments.DeploymentGroup
alias NervesHub.Repo
alias NimbleCSV.RFC4180, as: CSV

Expand Down Expand Up @@ -58,8 +58,8 @@ defmodule NervesHub.AuditLogs do
|> Flop.run(flop)
end

defp query_for_feed(%Deployment{id: id}) do
resource_type = to_string(Deployment)
defp query_for_feed(%DeploymentGroup{id: id}) do
resource_type = to_string(DeploymentGroup)

from(al in AuditLog, where: [resource_type: ^resource_type, resource_id: ^id])
|> order_by(desc: :inserted_at)
Expand Down
12 changes: 6 additions & 6 deletions lib/nerves_hub/audit_logs/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule NervesHub.AuditLogs.Templates do
def audit_resolve_changed_deployment(device, reference_id) do
description =
if device.deployment_id do
"device #{device.identifier} reloaded deployment and is attached to deployment #{device.deployment.name}"
"device #{device.identifier} reloaded deployment and is attached to deployment #{device.deployment_group.name}"
else
"device #{device.identifier} reloaded deployment and is no longer attached to a deployment"
end
Expand All @@ -15,18 +15,18 @@ defmodule NervesHub.AuditLogs.Templates do
end

def audit_device_deployment_update_triggered(device, reference_id) do
deployment = device.deployment
firmware = deployment.firmware
deployment_group = device.deployment_group
firmware = deployment_group.firmware

description =
"deployment #{deployment.name} update triggered device #{device.identifier} to update firmware #{firmware.uuid}"
"deployment #{deployment_group.name} update triggered device #{device.identifier} to update firmware #{firmware.uuid}"

AuditLogs.audit_with_ref!(deployment, device, description, reference_id)
AuditLogs.audit_with_ref!(deployment_group, device, description, reference_id)
end

def audit_device_assigned(device, reference_id) do
description =
"device #{device.identifier} reloaded deployment and is attached to deployment #{device.deployment.name}"
"device #{device.identifier} reloaded deployment and is attached to deployment #{device.deployment_group.name}"

AuditLogs.audit_with_ref!(device, device, description, reference_id)
end
Expand Down
15 changes: 0 additions & 15 deletions lib/nerves_hub/deployments/inflight_deployment_check.ex

This file was deleted.

19 changes: 0 additions & 19 deletions lib/nerves_hub/deployments/supervisor.ex

This file was deleted.

52 changes: 22 additions & 30 deletions lib/nerves_hub/devices.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ defmodule NervesHub.Devices do
alias NervesHub.Accounts.User
alias NervesHub.AuditLogs
alias NervesHub.Certificate
alias NervesHub.Deployments.Deployment
alias NervesHub.Deployments.Orchestrator
alias NervesHub.ManagedDeployments.DeploymentGroup
alias NervesHub.ManagedDeployments.Orchestrator
alias NervesHub.Devices.CACertificate
alias NervesHub.Devices.Alarms
alias NervesHub.Devices.Connections
Expand Down Expand Up @@ -86,12 +86,12 @@ defmodule NervesHub.Devices do
|> where([d], d.product_id == ^product_id)
|> join(:left, [d], o in assoc(d, :org))
|> join(:left, [d, o], p in assoc(d, :product))
|> join(:left, [d, o, p], dp in assoc(d, :deployment))
|> join(:left, [d, o, p], dp in assoc(d, :deployment_group))
|> join(:left, [d, o, p, dp], f in assoc(dp, :firmware))
|> Repo.exclude_deleted()
|> order_by(^sort_devices(sorting))
|> filtering(filters)
|> preload([d, o, p, dp, f], org: o, product: p, deployment: {dp, firmware: f})
|> preload([d, o, p, dp, f], org: o, product: p, deployment_group: {dp, firmware: f})
|> Connections.preload_latest_connection()
|> Flop.run(flop)
end
Expand Down Expand Up @@ -365,7 +365,7 @@ defmodule NervesHub.Devices do
{:error, :not_found}

device ->
{:ok, Repo.preload(device, [:org, :product, deployment: [:firmware]])}
{:ok, Repo.preload(device, [:org, :product, deployment_group: [:firmware]])}
end
end

Expand All @@ -392,9 +392,9 @@ defmodule NervesHub.Devices do
|> where(identifier: ^identifier)
|> where(org_id: ^org_id)
|> join(:left, [d], o in assoc(d, :org))
|> join(:left, [d], dp in assoc(d, :deployment))
|> join(:left, [d], dp in assoc(d, :deployment_group))
|> join_and_preload(preload_assoc)
|> preload([d, o, dp], org: o, deployment: dp)
|> preload([d, o, dp], org: o, deployment_group: dp)
end

defp join_and_preload(query, nil), do: query
Expand Down Expand Up @@ -466,7 +466,7 @@ defmodule NervesHub.Devices do

def get_eligible_deployments(%Device{firmware_metadata: meta} = device) do
from(
d in Deployment,
d in DeploymentGroup,
join: p in assoc(d, :product),
on: [org_id: ^device.org_id, name: ^meta.product],
join: f in assoc(d, :firmware),
Expand Down Expand Up @@ -736,7 +736,7 @@ defmodule NervesHub.Devices do
@spec get_device_firmware_for_delta_generation_by_product(binary()) ::
list({source_firmware_id(), target_firmware_id()})
def get_device_firmware_for_delta_generation_by_product(product_id) do
Deployment
DeploymentGroup
|> where([dep], dep.product_id == ^product_id)
|> join(:inner, [dep], dev in Device, on: dev.deployment_id == dep.id)
|> join(:inner, [dep, dev], f in Firmware,
Expand All @@ -751,7 +751,7 @@ defmodule NervesHub.Devices do
@spec get_device_firmware_for_delta_generation_by_deployment(binary()) ::
list({source_firmware_id(), target_firmware_id()})
def get_device_firmware_for_delta_generation_by_deployment(deployment_id) do
Deployment
DeploymentGroup
|> where([dep], dep.id == ^deployment_id)
|> join(:inner, [dep], dev in Device, on: dev.deployment_id == dep.id)
|> join(:inner, [dep, dev], f in Firmware,
Expand Down Expand Up @@ -817,7 +817,7 @@ defmodule NervesHub.Devices do
end

def resolve_update(device) do
deployment = Repo.preload(device.deployment, [:firmware])
deployment = Repo.preload(device.deployment_group, [:firmware])

case verify_update_eligibility(device, deployment) do
{:ok, _device} ->
Expand All @@ -828,7 +828,7 @@ defmodule NervesHub.Devices do
update_available: true,
firmware_url: url,
firmware_meta: meta,
deployment: deployment,
deployment_group: deployment,
deployment_id: deployment.id
}

Expand Down Expand Up @@ -860,7 +860,7 @@ defmodule NervesHub.Devices do
"""
def matches_deployment?(
%Device{tags: tags, firmware_metadata: %FirmwareMetadata{version: version}},
%Deployment{conditions: %{"version" => requirement, "tags" => dep_tags}}
%DeploymentGroup{conditions: %{"version" => requirement, "tags" => dep_tags}}
) do
if version_match?(version, requirement) and tags_match?(tags, dep_tags) do
true
Expand All @@ -871,29 +871,21 @@ defmodule NervesHub.Devices do

def matches_deployment?(_, _), do: false

@spec update_deployment(Device.t(), Deployment.t()) :: Device.t()
@spec update_deployment(Device.t(), DeploymentGroup.t()) :: Device.t()
def update_deployment(device, deployment) do
device
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_change(:deployment_id, deployment.id)
|> Repo.update!()
end

@spec clear_deployment(Device.t()) :: Device.t()
def clear_deployment(device) do
device
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_change(:deployment_id, nil)
|> Repo.update!()
end

@spec failure_threshold_met?(Device.t(), Deployment.t()) :: boolean()
def failure_threshold_met?(%Device{} = device, %Deployment{} = deployment) do
@spec failure_threshold_met?(Device.t(), DeploymentGroup.t()) :: boolean()
def failure_threshold_met?(%Device{} = device, %DeploymentGroup{} = deployment) do
Enum.count(device.update_attempts) >= deployment.device_failure_threshold
end

@spec failure_rate_met?(Device.t(), Deployment.t()) :: boolean()
def failure_rate_met?(%Device{} = device, %Deployment{} = deployment) do
@spec failure_rate_met?(Device.t(), DeploymentGroup.t()) :: boolean()
def failure_rate_met?(%Device{} = device, %DeploymentGroup{} = deployment) do
seconds_ago =
Timex.shift(DateTime.utc_now(), seconds: -deployment.device_failure_rate_seconds)

Expand Down Expand Up @@ -1021,7 +1013,7 @@ defmodule NervesHub.Devices do
if inflight_update != nil do
Orchestrator.device_updated(inflight_update.deployment_id)

Deployment
DeploymentGroup
|> where([d], d.id == ^inflight_update.deployment_id)
|> Repo.update_all(inc: [current_updated_devices: 1])

Expand Down Expand Up @@ -1086,7 +1078,7 @@ defmodule NervesHub.Devices do
|> Repo.transaction()
|> case do
{:ok, %{move: updated}} ->
_ = broadcast(updated, "moved")
# Deployments.set_deployment(updated)
{:ok, updated}

err ->
Expand Down Expand Up @@ -1387,14 +1379,14 @@ defmodule NervesHub.Devices do
|> Repo.update!()
end

def inflight_updates_for(%Deployment{} = deployment) do
def inflight_updates_for(%DeploymentGroup{} = deployment) do
InflightUpdate
|> where([iu], iu.deployment_id == ^deployment.id)
|> preload([:device])
|> Repo.all()
end

def count_inflight_updates_for(%Deployment{} = deployment) do
def count_inflight_updates_for(%DeploymentGroup{} = deployment) do
InflightUpdate
|> select([iu], count(iu))
|> where([iu], iu.deployment_id == ^deployment.id)
Expand Down
4 changes: 2 additions & 2 deletions lib/nerves_hub/devices/device.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ defmodule NervesHub.Devices.Device do
alias NervesHub.Devices.DeviceCertificate
alias NervesHub.Devices.DeviceConnection
alias NervesHub.Devices.DeviceMetric
alias NervesHub.Deployments.Deployment
alias NervesHub.Extensions.DeviceExtensionsSetting
alias NervesHub.ManagedDeployments.DeploymentGroup
alias NervesHub.Firmwares.FirmwareMetadata
alias NervesHub.Products.Product

Expand Down Expand Up @@ -40,7 +40,7 @@ defmodule NervesHub.Devices.Device do
schema "devices" do
belongs_to(:org, Org, where: [deleted_at: nil])
belongs_to(:product, Product, where: [deleted_at: nil])
belongs_to(:deployment, Deployment)
belongs_to(:deployment_group, DeploymentGroup, foreign_key: :deployment_id)
embeds_one(:firmware_metadata, FirmwareMetadata, on_replace: :update)
has_many(:device_certificates, DeviceCertificate, on_delete: :delete_all)
has_many(:device_connections, DeviceConnection, on_delete: :delete_all)
Expand Down
4 changes: 2 additions & 2 deletions lib/nerves_hub/devices/inflight_update.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ defmodule NervesHub.Devices.InflightUpdate do

alias NervesHub.Devices.Device
alias NervesHub.Devices.InflightUpdate
alias NervesHub.Deployments.Deployment
alias NervesHub.ManagedDeployments.DeploymentGroup
alias NervesHub.Firmwares.Firmware

@required_params [:device_id, :deployment_id, :firmware_id, :firmware_uuid, :expires_at]

schema "inflight_updates" do
belongs_to(:device, Device)
belongs_to(:deployment, Deployment)
belongs_to(:deployment_group, DeploymentGroup, foreign_key: :deployment_id)
belongs_to(:firmware, Firmware)

field(:firmware_uuid, Ecto.UUID)
Expand Down
8 changes: 4 additions & 4 deletions lib/nerves_hub/devices/update_payload.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule NervesHub.Devices.UpdatePayload do
"""

alias NervesHub.Firmwares.FirmwareMetadata
alias NervesHub.Deployments.Deployment
alias NervesHub.ManagedDeployments.DeploymentGroup

@derive {Jason.Encoder,
only: [
Expand All @@ -17,22 +17,22 @@ defmodule NervesHub.Devices.UpdatePayload do
defstruct update_available: false,
firmware_url: nil,
firmware_meta: nil,
deployment: nil,
deployment_group: nil,
deployment_id: nil

@type t ::
%__MODULE__{
update_available: false,
firmware_meta: nil,
firmware_url: nil,
deployment: nil,
deployment_group: nil,
deployment_id: nil
}
| %__MODULE__{
update_available: true,
firmware_meta: FirmwareMetadata.t(),
firmware_url: String.t(),
deployment: Deployment.t(),
deployment_group: DeploymentGroup.t(),
deployment_id: non_neg_integer()
}
end
10 changes: 5 additions & 5 deletions lib/nerves_hub/firmwares/firmware.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule NervesHub.Firmwares.Firmware do

alias NervesHub.Accounts.Org
alias NervesHub.Accounts.OrgKey
alias NervesHub.Deployments.Deployment
alias NervesHub.ManagedDeployments.DeploymentGroup
alias NervesHub.Products.Product

alias __MODULE__
Expand Down Expand Up @@ -46,7 +46,7 @@ defmodule NervesHub.Firmwares.Firmware do
belongs_to(:org, Org, where: [deleted_at: nil])
belongs_to(:product, Product, where: [deleted_at: nil])
belongs_to(:org_key, OrgKey)
has_many(:deployments, Deployment)
has_many(:deployment_groups, DeploymentGroup)

field(:architecture, :string)
field(:author, :string)
Expand All @@ -68,20 +68,20 @@ defmodule NervesHub.Firmwares.Firmware do
|> cast(params, @required_params ++ @optional_params)
|> validate_required(@required_params)
|> unique_constraint(:uuid, name: :firmwares_product_id_uuid_index)
|> foreign_key_constraint(:deployments, name: :deployments_firmware_id_fkey)
|> foreign_key_constraint(:deployment_groups, name: :deployment_groups_firmware_id_fkey)
end

def update_changeset(%Firmware{} = firmware, params) do
firmware
|> cast(params, @required_params ++ @optional_params)
|> validate_required(@required_params)
|> unique_constraint(:uuid, name: :firmwares_product_id_uuid_index)
|> foreign_key_constraint(:deployments, name: :deployments_firmware_id_fkey)
|> foreign_key_constraint(:deployment_groups, name: :deployment_groups_firmware_id_fkey)
end

def delete_changeset(%Firmware{} = firmware, params) do
firmware
|> cast(params, @required_params ++ @optional_params)
|> no_assoc_constraint(:deployments, message: "Firmware has associated deployments")
|> no_assoc_constraint(:deployment_groups, message: "Firmware has associated deployments")
end
end
Loading