Deployment and lifecycle management for Nix
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

server/agent: continue deployment build out

+99 -58
+34 -15
apps/sower/lib/sower/orchestration.ex
··· 179 179 """ 180 180 def list_subscriptions do 181 181 Repo.all(Subscription) 182 - |> Sower.Repo.preload(:agent) 182 + |> Sower.Repo.preload([:agent, :seed]) 183 183 end 184 184 185 185 @doc """ ··· 223 223 |> Repo.preload(:seed) 224 224 end 225 225 226 + def get_subscription_sids(sids) when is_list(sids) and length(sids) > 0 do 227 + query = from sub in Subscription, where: sub.sid in ^sids 228 + 229 + Repo.all(query) 230 + |> Repo.preload(:seed) 231 + end 232 + 233 + def get_subscription_sids(sids) when is_list(sids) and length(sids) == 0 do 234 + {:error, :no_sids_provided} 235 + end 236 + 226 237 @doc """ 227 238 Creates a subscription. 228 239 ··· 236 247 237 248 """ 238 249 def create_subscription(attrs \\ %{}) do 239 - %Subscription{ 240 - org_id: Sower.Repo.get_org_id() 241 - } 242 - |> Subscription.changeset(attrs) 243 - |> Repo.insert( 244 - on_conflict: {:replace, [:updated_at]}, 245 - conflict_target: [:agent_id, :seed_id, :org_id] 246 - ) 250 + case %Subscription{ 251 + org_id: Sower.Repo.get_org_id() 252 + } 253 + |> Subscription.changeset(attrs) 254 + |> Repo.insert( 255 + on_conflict: {:replace, [:updated_at]}, 256 + conflict_target: [:agent_id, :seed_id, :org_id] 257 + ) do 258 + {:ok, sub} -> {:ok, Repo.reload(sub)} 259 + err -> err 260 + end 247 261 end 248 262 249 263 @doc """ ··· 397 411 Request and create a deployment for a subscription 398 412 """ 399 413 def request_subscription_deployment( 400 - %SowerClient.Schemas.Subscription.UpgradeRequest{} = upgrade 414 + %SowerClient.Schemas.Orchestration.UpgradeRequest{} = upgrade 401 415 ) do 402 - with sub when not is_nil(sub) <- get_subscription_sid(upgrade.subscription_sid), 403 - seed_store_path <- Sower.Seed.latest_store_path(sub.seed), 416 + with subs when length(subs) > 0 <- get_subscription_sids(upgrade.subscription_sids), 417 + seed_store_paths <- 418 + subs |> Enum.map(&Sower.Seed.latest_store_path(&1.seed)) |> Enum.map(& &1.store_path), 404 419 {:ok, deploy} <- 405 420 create_deployment(%{ 406 - store_paths: [seed_store_path.store_path], 407 - subscription: sub 421 + store_paths: seed_store_paths, 422 + subscriptions: subs 408 423 }) do 409 424 {:ok, 410 - %SowerClient.Schemas.Orchestration.Deployment{subscription_sid: sub.sid, sid: deploy.sid}} 425 + %SowerClient.Schemas.Orchestration.Deployment{ 426 + request_id: upgrade.request_id, 427 + subscription_sids: Enum.map(subs, & &1.sid), 428 + sid: deploy.sid 429 + }} 411 430 else 412 431 {:error, _} = err -> 413 432 err
+2 -2
apps/sower/lib/sower/orchestration/subscription.ex
··· 5 5 @derive {Jason.Encoder, only: [:sid]} 6 6 @derive {Phoenix.Param, key: :sid} 7 7 8 - alias Sower.Orchestration.{Agent, Deployment} 8 + alias Sower.Orchestration.{Agent, Deployment, SubscriptionDeployment} 9 9 10 10 schema "subscriptions" do 11 11 field :sid, Sower.Schema.Sid, autogenerate: true ··· 14 14 belongs_to :agent, Agent 15 15 belongs_to :seed, Sower.Seed 16 16 17 - has_many :deployments, Deployment 17 + many_to_many :deployments, Deployment, join_through: SubscriptionDeployment 18 18 19 19 timestamps(type: :utc_datetime) 20 20 end
+9 -5
apps/sower/lib/sower_web/agent_channel.ex
··· 114 114 end 115 115 116 116 def handle_in("subscription:register", payload, socket) do 117 - with {:ok, req_sub} <- SowerClient.Schemas.Subscription.cast(payload), 117 + with {:ok, req_sub} <- SowerClient.Schemas.Orchestration.Subscription.cast(payload), 118 118 seed when not is_nil(seed) <- Sower.Seed.get(req_sub.name, req_sub.seed_type), 119 119 {:ok, subscription} <- 120 120 Sower.Orchestration.create_subscription(%{ ··· 122 122 seed_id: seed.id 123 123 }) do 124 124 subscription = 125 - req_sub 126 - |> Map.merge(%{subscription_sid: subscription.sid, seed_sid: seed.sid}) 127 - |> SowerClient.Schemas.Subscription.cast() 125 + SowerClient.Schemas.Orchestration.Subscription.cast(%{ 126 + sid: subscription.sid, 127 + local_sid: req_sub.local_sid, 128 + seed_sid: seed.sid, 129 + name: seed.name, 130 + seed_type: seed.seed_type 131 + }) 128 132 129 133 {:reply, subscription, socket} 130 134 else ··· 138 142 end 139 143 140 144 def handle_in("subscription:upgrade", payload, socket) do 141 - with {:ok, req_sub} <- SowerClient.Schemas.Subscription.UpgradeRequest.cast(payload), 145 + with {:ok, req_sub} <- SowerClient.Schemas.Orchestration.UpgradeRequest.cast(payload), 142 146 {:ok, deploy} <- Sower.Orchestration.request_subscription_deployment(req_sub) do 143 147 {:reply, {:ok, deploy}, socket} 144 148 else
+1 -1
apps/sower_agent/lib/sower_agent/config.ex
··· 30 30 }, 31 31 subscriptions: %Schema{ 32 32 type: :array, 33 - items: SowerClient.Schemas.Subscription.schema() 33 + items: SowerClient.Schemas.Orchestration.Subscription.schema() 34 34 } 35 35 }, 36 36 required: ~w(access_token endpoint)a
+5 -4
apps/sower_agent/lib/sower_agent/socket_client.ex
··· 40 40 41 41 def handle_call({:subscription_upgrade, sid}, _from, socket) do 42 42 with {:ok, upgrade_request} <- 43 - SowerClient.Schemas.Subscription.UpgradeRequest.cast(%{ 44 - subscription_sid: sid 43 + SowerClient.Schemas.Orchestration.UpgradeRequest.cast(%{ 44 + subscription_sids: [sid] 45 45 }), 46 46 {:ok, ref} <- 47 47 push(socket, private_channel(), "subscription:upgrade", upgrade_request), ··· 53 53 Logger.error( 54 54 msg: "Failed to request subscription upgrade", 55 55 error: error, 56 - subscription_sid: sid 56 + sid: sid 57 57 ) 58 58 59 59 {:reply, {:error, error}, socket} ··· 82 82 |> Enum.map(fn sub -> 83 83 with {:ok, ref} <- push(socket, private_channel(), "subscription:register", sub), 84 84 {:ok, subscription} <- await_reply(ref), 85 - {:ok, subscription} <- SowerClient.Schemas.Subscription.cast(subscription) do 85 + {:ok, subscription} <- 86 + SowerClient.Schemas.Orchestration.Subscription.cast(subscription) do 86 87 subscription 87 88 else 88 89 {:error, error} ->
+1 -1
apps/sower_agent/lib/sower_agent/storage.ex
··· 10 10 field :local_sid, String.t() 11 11 field :agent_sid, String.t() 12 12 13 - field :subscriptions, list(SowerClient.Schemas.Subscription) 13 + field :subscriptions, list(SowerClient.Schemas.Orchestration.Subscription) 14 14 end 15 15 16 16 # client
+13 -5
apps/sower_client/lib/schemas/orchestration/deployment.ex
··· 5 5 title: "Deployment", 6 6 type: :object, 7 7 properties: %{ 8 - sid: %Schema{ 8 + request_id: %Schema{ 9 9 type: :string, 10 - description: "deployment sid allocated by Sower", 10 + description: "request sid, autogenerated", 11 11 readOnly: true 12 12 }, 13 - subscription_sid: %Schema{ 13 + sid: %Schema{ 14 14 type: :string, 15 - description: "subscription sid allocated by Sower", 15 + description: "deployment sid allocated by Sower", 16 16 readOnly: true 17 17 }, 18 + subscription_sids: %Schema{ 19 + type: :array, 20 + items: %Schema{ 21 + type: :string, 22 + description: "subscription sids in deployment", 23 + readOnly: true 24 + } 25 + }, 18 26 deployed_at: %Schema{ 19 27 type: :string, 20 28 format: :date_time, ··· 22 30 default: DateTime.from_unix!(0) |> DateTime.to_iso8601() 23 31 } 24 32 }, 25 - required: ~w(subscription_sid)a 33 + required: ~w(subscription_sids)a 26 34 }) 27 35 end
+25
apps/sower_client/lib/schemas/orchestration/upgrade_request.ex
··· 1 + defmodule SowerClient.Schemas.Orchestration.UpgradeRequest do 2 + use SowerClient.Schema 3 + 4 + OpenApiSpex.schema(%{ 5 + title: "SubscriptionUpgradeRequest", 6 + type: :object, 7 + properties: %{ 8 + request_id: %Schema{ 9 + type: :string, 10 + description: "request sid, autogenerated", 11 + readOnly: true, 12 + default: "req_#{Cuid2Ex.create()}" 13 + }, 14 + subscription_sids: %Schema{ 15 + type: :array, 16 + items: %Schema{ 17 + type: :string, 18 + description: "subscription sid allocated by Sower", 19 + readOnly: true 20 + } 21 + } 22 + }, 23 + required: ~w(subscription_sids)a 24 + }) 25 + end
+9 -9
apps/sower_client/lib/schemas/subscription.ex apps/sower_client/lib/schemas/orchestration/subscription.ex
··· 1 - defmodule SowerClient.Schemas.Subscription do 1 + defmodule SowerClient.Schemas.Orchestration.Subscription do 2 2 use SowerClient.Schema 3 3 4 4 OpenApiSpex.schema(%{ 5 5 title: "Subscription", 6 6 type: :object, 7 7 properties: %{ 8 + sid: %Schema{ 9 + type: :string, 10 + description: "subscription sid allocated by Sower", 11 + readOnly: true, 12 + nullable: true 13 + }, 8 14 local_sid: %Schema{ 9 15 type: :string, 10 16 description: "sid allocated locally", ··· 14 20 type: :string, 15 21 description: "Name of the seed" 16 22 }, 17 - seed_sid: %Schema{ 18 - type: :string, 19 - description: "seed sid allocated by Sower", 20 - readOnly: true, 21 - nullable: true 22 - }, 23 23 seed_type: %Schema{ 24 24 type: :string, 25 25 description: "Type of the seed", 26 26 enum: SowerClient.Schemas.Seed.seed_types() 27 27 }, 28 - subscription_sid: %Schema{ 28 + seed_sid: %Schema{ 29 29 type: :string, 30 - description: "subscription sid allocated by Sower", 30 + description: "seed sid allocated by Sower", 31 31 readOnly: true, 32 32 nullable: true 33 33 }
-16
apps/sower_client/lib/schemas/subscription/upgrade_request.ex
··· 1 - defmodule SowerClient.Schemas.Subscription.UpgradeRequest do 2 - use SowerClient.Schema 3 - 4 - OpenApiSpex.schema(%{ 5 - title: "SubscriptionUpgradeRequest", 6 - type: :object, 7 - properties: %{ 8 - subscription_sid: %Schema{ 9 - type: :string, 10 - description: "subscription sid allocated by Sower", 11 - readOnly: true 12 - } 13 - }, 14 - required: ~w(subscription_sid)a 15 - }) 16 - end