mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-11-10 06:01:44 +08:00
Get App Settings fields from WebSocket event (#2571)
This commit is contained in:
parent
6a756b415f
commit
5e7f8a477a
13 changed files with 60 additions and 36 deletions
|
|
@ -417,6 +417,8 @@ defmodule Livebook.Hubs.TeamClient do
|
||||||
slug: app_deployment.slug,
|
slug: app_deployment.slug,
|
||||||
sha: app_deployment.sha,
|
sha: app_deployment.sha,
|
||||||
title: app_deployment.title,
|
title: app_deployment.title,
|
||||||
|
multi_session: app_deployment.multi_session,
|
||||||
|
access_type: String.to_atom(app_deployment.access_type),
|
||||||
hub_id: state.hub.id,
|
hub_id: state.hub.id,
|
||||||
deployment_group_id: app_deployment.deployment_group_id,
|
deployment_group_id: app_deployment.deployment_group_id,
|
||||||
file: nil,
|
file: nil,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ defmodule Livebook.Notebook.AppSettings do
|
||||||
@type access_type :: :public | :protected
|
@type access_type :: :public | :protected
|
||||||
@type output_type :: :all | :rich
|
@type output_type :: :all | :rich
|
||||||
|
|
||||||
|
@access_types [:public, :protected]
|
||||||
|
|
||||||
@primary_key false
|
@primary_key false
|
||||||
embedded_schema do
|
embedded_schema do
|
||||||
field :slug, :string
|
field :slug, :string
|
||||||
|
|
@ -27,7 +29,7 @@ defmodule Livebook.Notebook.AppSettings do
|
||||||
field :zero_downtime, :boolean
|
field :zero_downtime, :boolean
|
||||||
field :show_existing_sessions, :boolean
|
field :show_existing_sessions, :boolean
|
||||||
field :auto_shutdown_ms, :integer
|
field :auto_shutdown_ms, :integer
|
||||||
field :access_type, Ecto.Enum, values: [:public, :protected]
|
field :access_type, Ecto.Enum, values: @access_types
|
||||||
field :password, :string
|
field :password, :string
|
||||||
field :show_source, :boolean
|
field :show_source, :boolean
|
||||||
field :output_type, Ecto.Enum, values: [:all, :rich]
|
field :output_type, Ecto.Enum, values: [:all, :rich]
|
||||||
|
|
@ -153,4 +155,10 @@ defmodule Livebook.Notebook.AppSettings do
|
||||||
def valid?(settings) do
|
def valid?(settings) do
|
||||||
change(settings).valid?
|
change(settings).valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns a list of possible access types.
|
||||||
|
"""
|
||||||
|
@spec access_types() :: list(atom())
|
||||||
|
def access_types(), do: @access_types
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ defmodule Livebook.Teams do
|
||||||
alias Livebook.Hubs
|
alias Livebook.Hubs
|
||||||
alias Livebook.Hubs.Team
|
alias Livebook.Hubs.Team
|
||||||
alias Livebook.Hubs.TeamClient
|
alias Livebook.Hubs.TeamClient
|
||||||
alias Livebook.Notebook.AppSettings
|
|
||||||
alias Livebook.Teams.{Agent, AppDeployment, DeploymentGroup, Org, Requests}
|
alias Livebook.Teams.{Agent, AppDeployment, DeploymentGroup, Org, Requests}
|
||||||
|
|
||||||
import Ecto.Changeset,
|
import Ecto.Changeset,
|
||||||
|
|
@ -191,12 +190,12 @@ defmodule Livebook.Teams do
|
||||||
@doc """
|
@doc """
|
||||||
Creates a new app deployment.
|
Creates a new app deployment.
|
||||||
"""
|
"""
|
||||||
@spec deploy_app(Team.t(), AppDeployment.t(), AppSettings.t()) ::
|
@spec deploy_app(Team.t(), AppDeployment.t()) ::
|
||||||
:ok
|
:ok
|
||||||
| {:error, Ecto.Changeset.t()}
|
| {:error, Ecto.Changeset.t()}
|
||||||
| {:transport_error, String.t()}
|
| {:transport_error, String.t()}
|
||||||
def deploy_app(%Team{} = team, %AppDeployment{} = app_deployment, %AppSettings{} = app_settings) do
|
def deploy_app(%Team{} = team, %AppDeployment{} = app_deployment) do
|
||||||
case Requests.deploy_app(team, app_deployment, app_settings) do
|
case Requests.deploy_app(team, app_deployment) do
|
||||||
{:ok, %{"id" => _id}} ->
|
{:ok, %{"id" => _id}} ->
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
|
|
@ -204,11 +203,6 @@ defmodule Livebook.Teams do
|
||||||
{:error, Requests.add_errors(app_deployment, %{"file" => [error]})}
|
{:error, Requests.add_errors(app_deployment, %{"file" => [error]})}
|
||||||
|
|
||||||
{:error, %{"errors" => errors}} ->
|
{:error, %{"errors" => errors}} ->
|
||||||
errors =
|
|
||||||
errors
|
|
||||||
|> map_teams_field_to_livebook_field("multi_session", "file")
|
|
||||||
|> map_teams_field_to_livebook_field("access_type", "file")
|
|
||||||
|
|
||||||
{:error, Requests.add_errors(app_deployment, errors)}
|
{:error, Requests.add_errors(app_deployment, errors)}
|
||||||
|
|
||||||
any ->
|
any ->
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ defmodule Livebook.Teams.AppDeployment do
|
||||||
slug: String.t() | nil,
|
slug: String.t() | nil,
|
||||||
sha: String.t() | nil,
|
sha: String.t() | nil,
|
||||||
title: String.t() | nil,
|
title: String.t() | nil,
|
||||||
|
multi_session: boolean(),
|
||||||
|
access_type: Livebook.Notebook.AppSettings.access_type(),
|
||||||
hub_id: String.t() | nil,
|
hub_id: String.t() | nil,
|
||||||
deployment_group_id: String.t() | nil,
|
deployment_group_id: String.t() | nil,
|
||||||
file: binary() | nil,
|
file: binary() | nil,
|
||||||
|
|
@ -16,11 +18,15 @@ defmodule Livebook.Teams.AppDeployment do
|
||||||
deployed_at: NaiveDateTime.t() | nil
|
deployed_at: NaiveDateTime.t() | nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@access_types Livebook.Notebook.AppSettings.access_types()
|
||||||
|
|
||||||
@primary_key {:id, :string, autogenerate: false}
|
@primary_key {:id, :string, autogenerate: false}
|
||||||
embedded_schema do
|
embedded_schema do
|
||||||
field :slug, :string
|
field :slug, :string
|
||||||
field :sha, :string
|
field :sha, :string
|
||||||
field :title, :string
|
field :title, :string
|
||||||
|
field :multi_session, :boolean
|
||||||
|
field :access_type, Ecto.Enum, values: @access_types
|
||||||
field :hub_id, :string
|
field :hub_id, :string
|
||||||
field :deployment_group_id, :string
|
field :deployment_group_id, :string
|
||||||
field :file, :string
|
field :file, :string
|
||||||
|
|
@ -47,6 +53,8 @@ defmodule Livebook.Teams.AppDeployment do
|
||||||
slug: notebook.app_settings.slug,
|
slug: notebook.app_settings.slug,
|
||||||
sha: shasum,
|
sha: shasum,
|
||||||
title: notebook.name,
|
title: notebook.name,
|
||||||
|
multi_session: notebook.app_settings.multi_session,
|
||||||
|
access_type: notebook.app_settings.access_type,
|
||||||
hub_id: notebook.hub_id,
|
hub_id: notebook.hub_id,
|
||||||
deployment_group_id: notebook.deployment_group_id,
|
deployment_group_id: notebook.deployment_group_id,
|
||||||
file: zip_content
|
file: zip_content
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ defmodule Livebook.Teams.Requests do
|
||||||
alias Livebook.FileSystem
|
alias Livebook.FileSystem
|
||||||
alias Livebook.FileSystems
|
alias Livebook.FileSystems
|
||||||
alias Livebook.Hubs.Team
|
alias Livebook.Hubs.Team
|
||||||
alias Livebook.Notebook.AppSettings
|
|
||||||
alias Livebook.Secrets.Secret
|
alias Livebook.Secrets.Secret
|
||||||
alias Livebook.Teams
|
alias Livebook.Teams
|
||||||
alias Livebook.Teams.{AppDeployment, DeploymentGroup, Org}
|
alias Livebook.Teams.{AppDeployment, DeploymentGroup, Org}
|
||||||
|
|
@ -184,16 +183,16 @@ defmodule Livebook.Teams.Requests do
|
||||||
@doc """
|
@doc """
|
||||||
Send a request to Livebook Team API to deploy an app.
|
Send a request to Livebook Team API to deploy an app.
|
||||||
"""
|
"""
|
||||||
@spec deploy_app(Team.t(), AppDeployment.t(), AppSettings.t()) ::
|
@spec deploy_app(Team.t(), AppDeployment.t()) ::
|
||||||
{:ok, map()} | {:error, map() | String.t()} | {:transport_error, String.t()}
|
{:ok, map()} | {:error, map() | String.t()} | {:transport_error, String.t()}
|
||||||
def deploy_app(team, app_deployment, app_settings) do
|
def deploy_app(team, app_deployment) do
|
||||||
secret_key = Teams.derive_key(team.teams_key)
|
secret_key = Teams.derive_key(team.teams_key)
|
||||||
|
|
||||||
params = %{
|
params = %{
|
||||||
title: app_deployment.title,
|
title: app_deployment.title,
|
||||||
slug: app_deployment.slug,
|
slug: app_deployment.slug,
|
||||||
multi_session: app_settings.multi_session,
|
multi_session: app_deployment.multi_session,
|
||||||
access_type: app_settings.access_type,
|
access_type: app_deployment.access_type,
|
||||||
deployment_group_id: app_deployment.deployment_group_id,
|
deployment_group_id: app_deployment.deployment_group_id,
|
||||||
sha: app_deployment.sha
|
sha: app_deployment.sha
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,10 +165,8 @@ defmodule LivebookWeb.SessionLive.AppTeamsComponent do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("deploy_app", _, socket) do
|
def handle_event("deploy_app", _, socket) do
|
||||||
notebook = Livebook.Session.get_notebook(socket.assigns.session.pid)
|
with {:ok, app_deployment} <- pack_app(socket),
|
||||||
|
:ok <- deploy_app(socket, app_deployment) do
|
||||||
with {:ok, app_deployment} <- pack_app(socket, notebook),
|
|
||||||
:ok <- deploy_app(socket, app_deployment, notebook.app_settings) do
|
|
||||||
message =
|
message =
|
||||||
"App deployment for #{app_deployment.slug} with title #{app_deployment.title} created successfully"
|
"App deployment for #{app_deployment.slug} with title #{app_deployment.title} created successfully"
|
||||||
|
|
||||||
|
|
@ -176,7 +174,8 @@ defmodule LivebookWeb.SessionLive.AppTeamsComponent do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp pack_app(socket, notebook) do
|
defp pack_app(socket) do
|
||||||
|
notebook = Livebook.Session.get_notebook(socket.assigns.session.pid)
|
||||||
files_dir = socket.assigns.session.files_dir
|
files_dir = socket.assigns.session.files_dir
|
||||||
|
|
||||||
case Livebook.Teams.AppDeployment.new(notebook, files_dir) do
|
case Livebook.Teams.AppDeployment.new(notebook, files_dir) do
|
||||||
|
|
@ -193,8 +192,8 @@ defmodule LivebookWeb.SessionLive.AppTeamsComponent do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp deploy_app(socket, app_deployment, app_settings) do
|
defp deploy_app(socket, app_deployment) do
|
||||||
case Livebook.Teams.deploy_app(socket.assigns.hub, app_deployment, app_settings) do
|
case Livebook.Teams.deploy_app(socket.assigns.hub, app_deployment) do
|
||||||
:ok ->
|
:ok ->
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,6 @@ defmodule LivebookProto.AppDeployment do
|
||||||
field :deployment_group_id, 6, type: :string, json_name: "deploymentGroupId"
|
field :deployment_group_id, 6, type: :string, json_name: "deploymentGroupId"
|
||||||
field :deployed_by, 7, type: :string, json_name: "deployedBy"
|
field :deployed_by, 7, type: :string, json_name: "deployedBy"
|
||||||
field :deployed_at, 8, type: :int64, json_name: "deployedAt"
|
field :deployed_at, 8, type: :int64, json_name: "deployedAt"
|
||||||
|
field :multi_session, 9, type: :bool, json_name: "multiSession"
|
||||||
|
field :access_type, 10, type: :string, json_name: "accessType"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,8 @@ message AppDeployment {
|
||||||
string deployment_group_id = 6;
|
string deployment_group_id = 6;
|
||||||
string deployed_by = 7;
|
string deployed_by = 7;
|
||||||
int64 deployed_at = 8;
|
int64 deployed_at = 8;
|
||||||
|
bool multi_session = 9;
|
||||||
|
string access_type = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AppDeploymentStarted {
|
message AppDeploymentStarted {
|
||||||
|
|
|
||||||
|
|
@ -133,15 +133,19 @@ defmodule Livebook.Hubs.TeamClientTest do
|
||||||
|
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
||||||
{:ok, app_deployment} = Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
{:ok, app_deployment} = Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
||||||
:ok = Livebook.Teams.deploy_app(team, app_deployment, app_settings)
|
:ok = Livebook.Teams.deploy_app(team, app_deployment)
|
||||||
|
|
||||||
sha = app_deployment.sha
|
sha = app_deployment.sha
|
||||||
|
multi_session = app_settings.multi_session
|
||||||
|
access_type = app_settings.access_type
|
||||||
|
|
||||||
assert_receive {:app_deployment_started,
|
assert_receive {:app_deployment_started,
|
||||||
%Livebook.Teams.AppDeployment{
|
%Livebook.Teams.AppDeployment{
|
||||||
slug: ^slug,
|
slug: ^slug,
|
||||||
sha: ^sha,
|
sha: ^sha,
|
||||||
title: ^title,
|
title: ^title,
|
||||||
|
multi_session: ^multi_session,
|
||||||
|
access_type: ^access_type,
|
||||||
deployment_group_id: ^id
|
deployment_group_id: ^id
|
||||||
} = app_deployment}
|
} = app_deployment}
|
||||||
|
|
||||||
|
|
@ -357,7 +361,9 @@ defmodule Livebook.Hubs.TeamClientTest do
|
||||||
deployed_by: app_deployment.deployed_by,
|
deployed_by: app_deployment.deployed_by,
|
||||||
deployed_at: seconds,
|
deployed_at: seconds,
|
||||||
revision_id: "1",
|
revision_id: "1",
|
||||||
deployment_group_id: app_deployment.deployment_group_id
|
deployment_group_id: app_deployment.deployment_group_id,
|
||||||
|
multi_session: app_deployment.multi_session,
|
||||||
|
access_type: to_string(app_deployment.access_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
user_connected = %{
|
user_connected = %{
|
||||||
|
|
@ -770,7 +776,9 @@ defmodule Livebook.Hubs.TeamClientTest do
|
||||||
deployed_by: app_deployment.deployed_by,
|
deployed_by: app_deployment.deployed_by,
|
||||||
deployed_at: seconds,
|
deployed_at: seconds,
|
||||||
revision_id: to_string(teams_app_deployment.app_revision.id),
|
revision_id: to_string(teams_app_deployment.app_revision.id),
|
||||||
deployment_group_id: app_deployment.deployment_group_id
|
deployment_group_id: app_deployment.deployment_group_id,
|
||||||
|
multi_session: app_deployment.multi_session,
|
||||||
|
access_type: to_string(app_deployment.access_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
agent_connected = %{agent_connected | app_deployments: [livebook_proto_app_deployment]}
|
agent_connected = %{agent_connected | app_deployments: [livebook_proto_app_deployment]}
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ defmodule Livebook.Teams.ConnectionTest do
|
||||||
|
|
||||||
# since we want to fetch the app deployment from connection event,
|
# since we want to fetch the app deployment from connection event,
|
||||||
# we need to persist it before we connect to the WebSocket
|
# we need to persist it before we connect to the WebSocket
|
||||||
:ok = Livebook.Teams.deploy_app(hub, app_deployment, app_settings)
|
:ok = Livebook.Teams.deploy_app(hub, app_deployment)
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
||||||
assert_receive :connected
|
assert_receive :connected
|
||||||
|
|
@ -181,7 +181,7 @@ defmodule Livebook.Teams.ConnectionTest do
|
||||||
|
|
||||||
# since we want to fetch the app deployment from connection event,
|
# since we want to fetch the app deployment from connection event,
|
||||||
# we need to persist it before we connect to the WebSocket
|
# we need to persist it before we connect to the WebSocket
|
||||||
:ok = Livebook.Teams.deploy_app(hub, app_deployment, app_settings)
|
:ok = Livebook.Teams.deploy_app(hub, app_deployment)
|
||||||
|
|
||||||
# As we need to be Agent to receive the app deployments list to be deployed,
|
# As we need to be Agent to receive the app deployments list to be deployed,
|
||||||
# we will create another connection here
|
# we will create another connection here
|
||||||
|
|
|
||||||
|
|
@ -209,21 +209,21 @@ defmodule Livebook.TeamsTest do
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
||||||
|
|
||||||
assert {:ok, app_deployment} = Teams.AppDeployment.new(notebook, files_dir)
|
assert {:ok, app_deployment} = Teams.AppDeployment.new(notebook, files_dir)
|
||||||
assert Teams.deploy_app(team, app_deployment, app_settings) == :ok
|
assert Teams.deploy_app(team, app_deployment) == :ok
|
||||||
|
|
||||||
assert {:error,
|
assert {:error,
|
||||||
%{errors: [slug: {"should only contain alphanumeric characters and dashes", []}]}} =
|
%{errors: [slug: {"should only contain alphanumeric characters and dashes", []}]}} =
|
||||||
Teams.deploy_app(team, %{app_deployment | slug: "@abc"}, app_settings)
|
Teams.deploy_app(team, %{app_deployment | slug: "@abc"})
|
||||||
|
|
||||||
# Since the fields below belongs to AppSettings, we're mapping the errors to `:file` field.
|
# Since the fields below belongs to AppSettings, we're mapping the errors to `:file` field.
|
||||||
assert {:error, %{errors: [file: {"can't be blank", []}]}} =
|
assert {:error, %{errors: [multi_session: {"can't be blank", []}]}} =
|
||||||
Teams.deploy_app(team, app_deployment, %{app_settings | multi_session: nil})
|
Teams.deploy_app(team, %{app_deployment | multi_session: nil})
|
||||||
|
|
||||||
assert {:error, %{errors: [file: {"can't be blank", []}]}} =
|
assert {:error, %{errors: [access_type: {"can't be blank", []}]}} =
|
||||||
Teams.deploy_app(team, app_deployment, %{app_settings | access_type: nil})
|
Teams.deploy_app(team, %{app_deployment | access_type: nil})
|
||||||
|
|
||||||
assert {:error, %{errors: [file: {"is invalid", []}]}} =
|
assert {:error, %{errors: [access_type: {"is invalid", []}]}} =
|
||||||
Teams.deploy_app(team, app_deployment, %{app_settings | access_type: :abc})
|
Teams.deploy_app(team, %{app_deployment | access_type: :abc})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ defmodule LivebookWeb.Integration.Hub.DeploymentGroupTest do
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
||||||
|
|
||||||
{:ok, app_deployment} = Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
{:ok, app_deployment} = Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
||||||
:ok = Livebook.Teams.deploy_app(hub, app_deployment, app_settings)
|
:ok = Livebook.Teams.deploy_app(hub, app_deployment)
|
||||||
|
|
||||||
assert_receive {:app_deployment_started, _}
|
assert_receive {:app_deployment_started, _}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,8 @@ defmodule Livebook.Factory do
|
||||||
sha: shasum,
|
sha: shasum,
|
||||||
slug: slug,
|
slug: slug,
|
||||||
file: content,
|
file: content,
|
||||||
|
multi_session: false,
|
||||||
|
access_type: :protected,
|
||||||
hub_id: Livebook.Hubs.Personal.id(),
|
hub_id: Livebook.Hubs.Personal.id(),
|
||||||
deployment_group_id: "1",
|
deployment_group_id: "1",
|
||||||
deployed_by: "Ada Lovelace",
|
deployed_by: "Ada Lovelace",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue