Skip to content

Commit

Permalink
chore(tenants): tenant cleanup
Browse files Browse the repository at this point in the history
Closes #504.
Manages resource cleanup on tenant deletion, deleting base images,
ephemeral images and system models images on remote storage.

Signed-off-by: Luca Zaninotto <[email protected]>
  • Loading branch information
lusergit committed Jan 8, 2025
1 parent ad4cb42 commit 08747b1
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 10 deletions.
7 changes: 5 additions & 2 deletions backend/lib/edgehog/base_images/base_images.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of Edgehog.
#
# Copyright 2022-2024 SECO Mind Srl
# Copyright 2022-2025 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -67,7 +67,10 @@ defmodule Edgehog.BaseImages do
end

resources do
resource BaseImage
resource BaseImage do
define :delete_base_image, action: :destroy
end

resource BaseImageCollection
end
end
8 changes: 6 additions & 2 deletions backend/lib/edgehog/devices/devices.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of Edgehog.
#
# Copyright 2021-2024 SECO Mind Srl
# Copyright 2021-2025 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -86,7 +86,11 @@ defmodule Edgehog.Devices do
resource Device
resource HardwareType
resource Edgehog.Devices.HardwareTypePartNumber
resource SystemModel

resource SystemModel do
define :delete_system_model, action: :destroy
end

resource Edgehog.Devices.SystemModelPartNumber
end
end
1 change: 1 addition & 0 deletions backend/lib/edgehog/os_management/os_management.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ defmodule Edgehog.OSManagement do
define :mark_ota_operation_as_timed_out, action: :mark_as_timed_out
define :update_ota_operation_status, action: :update_status, args: [:status]
define :send_update_request, args: [:ota_operation]
define :delete_ota_operation, action: :destroy
end
end
end
12 changes: 10 additions & 2 deletions backend/lib/edgehog/os_management/ota_operation/ota_operation.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of Edgehog.
#
# Copyright 2022-2024 SECO Mind Srl
# Copyright 2022-2025 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -47,7 +47,7 @@ defmodule Edgehog.OSManagement.OTAOperation do
end

actions do
defaults [:read, :destroy]
defaults [:read]

create :create_fixture do
accept [
Expand Down Expand Up @@ -98,6 +98,14 @@ defmodule Edgehog.OSManagement.OTAOperation do
change {PublishNotification, event_type: :ota_operation_created}
end

destroy :destroy do
require_atomic? false

change Changes.HandleEphemeralImageDeletion do
where attribute_equals(:manual?, true)
end
end

update :mark_as_timed_out do
# Needed because PublishNotification and HandleEphemeralImageDeletion are not atomic
require_atomic? false
Expand Down
78 changes: 78 additions & 0 deletions backend/lib/edgehog/tenants/tenant/changes/handle_cleanup.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#
# This file is part of Edgehog.
#
# Copyright 2025 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

defmodule Edgehog.Tenants.Tenant.Changes.HandleCleanup do
@moduledoc false
use Ash.Resource.Change

alias Edgehog.BaseImages
alias Edgehog.BaseImages.BaseImage
alias Edgehog.Devices
alias Edgehog.Devices.SystemModel
alias Edgehog.OSManagement
alias Edgehog.OSManagement.OTAOperation

require Ash.Query

@impl Ash.Resource.Change
def change(changeset, _opts, _context) do
tenant = changeset.data

system_models = Ash.read!(SystemModel, tenant: tenant)

base_images = Ash.read!(BaseImage, tenant: tenant)

manual_otas =
OTAOperation
|> Ash.Query.filter(manual?)
|> Ash.read!(tenant: tenant)

Ash.Changeset.after_transaction(changeset, fn _changeset, result ->
with {:ok, tenant} <- result do
try do
cleanup_system_models(system_models, tenant)
cleanup_base_images(base_images, tenant)
cleanup_ephimeral_images(manual_otas, tenant)
{:ok, tenant}
rescue
e -> {:error, e}
end
end
end)
end

defp cleanup_system_models(system_models, tenant) do
for system_model <- system_models do
Devices.delete_system_model!(system_model, tenant: tenant)
end
end

defp cleanup_base_images(base_images, tenant) do
for image <- base_images do
BaseImages.delete_base_image!(image, tenant: tenant)
end
end

defp cleanup_ephimeral_images(manual_otas, tenant) do
for ota <- manual_otas do
OSManagement.delete_ota_operation!(ota, tenant: tenant)
end
end
end
10 changes: 9 additions & 1 deletion backend/lib/edgehog/tenants/tenant/tenant.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ defmodule Edgehog.Tenants.Tenant do
alias Ash.Error.Invalid.TenantRequired
alias Edgehog.Tenants.AstarteConfig
alias Edgehog.Tenants.Tenant
alias Edgehog.Tenants.Tenant.Changes
alias Edgehog.Validations

require Ash.Query
Expand Down Expand Up @@ -60,7 +61,7 @@ defmodule Edgehog.Tenants.Tenant do
end

actions do
defaults [:read, :destroy]
defaults [:read]

create :create do
primary? true
Expand Down Expand Up @@ -99,6 +100,13 @@ defmodule Edgehog.Tenants.Tenant do

run Tenant.ManualActions.ReconcilerAction
end

destroy :destroy do
description "Destroy tenant handling resource cleanup."

require_atomic? false
change Changes.HandleCleanup
end
end

validations do
Expand Down
21 changes: 18 additions & 3 deletions backend/test/edgehog/tenants_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of Edgehog.
#
# Copyright 2021-2024 SECO Mind Srl
# Copyright 2021-2025 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -28,6 +28,8 @@ defmodule Edgehog.TenantsTest do
alias Ash.Error.Invalid
alias Ash.Error.Query.NotFound
alias Edgehog.Astarte
alias Edgehog.BaseImages.StorageMock
alias Edgehog.OSManagement.EphemeralImageMock
alias Edgehog.Tenants
alias Edgehog.Tenants.ReconcilerMock
alias Edgehog.Tenants.Tenant
Expand Down Expand Up @@ -326,8 +328,21 @@ defmodule Edgehog.TenantsTest do
manual_ota_operation = manual_ota_operation_fixture(device_id: device.id, tenant: tenant)

update_channel = update_channel_fixture(tenant: tenant)
update_campaign = update_campaign_fixture(tenant: tenant)
update_target = target_fixture(tenant: tenant)
update_campaign = update_campaign_fixture(base_image_id: base_image.id, tenant: tenant)
update_target = target_fixture(base_image_id: base_image.id, tenant: tenant)

expect(StorageMock, :delete, fn to_delete ->
assert to_delete.id == base_image.id
:ok
end)

expect(EphemeralImageMock, :delete, fn tenant_id, ota_operation_id, url ->
assert tenant_id == manual_ota_operation.tenant_id
assert ota_operation_id == manual_ota_operation.id
assert url == manual_ota_operation.base_image_url

:ok
end)

assert :ok = Tenants.destroy_tenant(tenant)

Expand Down

0 comments on commit 08747b1

Please sign in to comment.