Simplify code that is no longer shared across views

This commit is contained in:
José Valim 2024-04-08 11:06:08 +02:00
parent 4c6869d69c
commit cb11b26cdc
9 changed files with 135 additions and 153 deletions

View file

@ -309,7 +309,7 @@ defmodule Livebook.Teams.Requests do
{:ok, %{status: 401}} ->
{:transport_error,
"You are not authorized to perform this action, make sure you have the access or you are not in a Livebook Agent/Offline instance"}
"You are not authorized to perform this action, make sure you have the access and you are not in a Livebook App Server/Offline instance"}
_otherwise ->
{:transport_error, @error_message}

View file

@ -82,30 +82,6 @@ defmodule LivebookWeb.AppComponents do
)
end
@doc """
Renders form fields for Dockerfile configuration.
"""
attr :form, Phoenix.HTML.Form, required: true
attr :hub, :map, required: true
attr :show_deploy_all, :boolean, default: true
def docker_config_form_content(assigns) do
~H"""
<div class="flex flex-col space-y-4">
<.radio_field
:if={@show_deploy_all}
label="Deploy"
field={@form[:deploy_all]}
options={[
{"false", "Only this notebook"},
{"true", "All notebooks in the current directory"}
]}
/>
<.radio_field label="Base image" field={@form[:docker_tag]} options={docker_tag_options()} />
</div>
"""
end
@doc """
Renders form fields for Deployment Group.
"""
@ -184,103 +160,18 @@ defmodule LivebookWeb.AppComponents do
defp zta_options(), do: @zta_options
@docker_tag_options for image <- Livebook.Config.docker_images(), do: {image.tag, image.name}
defp docker_tag_options(), do: @docker_tag_options
@doc """
Renders Docker deployment instruction for an app.
"""
attr :hub, :map, required: true
attr :dockerfile, :string, required: true
attr :dockerfile_config, :map, required: true
slot :dockerfile_actions, default: nil
def docker_instructions(assigns) do
~H"""
<div class="flex flex-col gap-4">
<div>
<div class="flex items-end mb-1 gap-1">
<span class="text-sm text-gray-700 font-semibold">Dockerfile</span>
<div class="grow" />
<%= render_slot(@dockerfile_actions) %>
<.button
color="gray"
small
data-tooltip="Copied to clipboard"
type="button"
aria-label="copy to clipboard"
phx-click={
JS.dispatch("lb:clipcopy", to: "#dockerfile-source")
|> JS.transition("tooltip top", time: 2000)
}
>
<.remix_icon icon="clipboard-line" />
<span>Copy source</span>
</.button>
</div>
<.code_preview source_id="dockerfile-source" source={@dockerfile} language="dockerfile" />
</div>
<div class="text-gray-700">
To test the deployment locally, go the the notebook directory, save the Dockerfile, then run:
</div>
<.code_preview
source_id="dockerfile-cmd"
source={
~s'''
docker build -t my-app .
docker run --rm -p 8080:8080 -p 8081:8081 my-app
'''
}
language="text"
/>
<p class="text-gray-700 py-2">
You may additionally perform the following optional steps:
</p>
<ul class="text-gray-700 space-y-3">
<li :if={Hubs.Provider.type(@hub) == "team"} class="flex gap-2">
<div><.remix_icon icon="arrow-right-line" class="text-gray-900" /></div>
<span>
you may remove the default value for <code>TEAMS_KEY</code>
from your Dockerfile and set it as a build argument in your deployment
platform
</span>
</li>
<li :if={@dockerfile_config.clustering} class="flex gap-2">
<div><.remix_icon icon="arrow-right-line" class="text-gray-900" /></div>
<span>
you may set <code>LIVEBOOK_SECRET_KEY_BASE</code>
and <code>LIVEBOOK_COOKIE</code>
as runtime environment secrets in your deployment platform, to ensure their
values stay the same across deployments. If you do that, you can remove
the defaults from your Dockerfile
</span>
</li>
<li class="flex gap-2">
<div><.remix_icon icon="arrow-right-line" class="text-gray-900" /></div>
<span>
if you want to debug your deployed notebooks in production, you may
set the <code>LIVEBOOK_PASSWORD</code> environment variable with a
value of at least 12 characters of your choice
</span>
</li>
</ul>
</div>
"""
end
defp zta_metadata(nil), do: nil
defp zta_metadata(zta_provider) do
Enum.find(Livebook.Config.identity_providers(), &(&1.type == zta_provider))
end
@doc """
Lists all docker tag options.
"""
@docker_tag_options for image <- Livebook.Config.docker_images(), do: {image.tag, image.name}
def docker_tag_options(), do: @docker_tag_options
@doc """
Updates app list with the given apps event.
"""

View file

@ -162,7 +162,8 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do
</h2>
<p class="text-gray-700">
Secrets are a safe way to share credentials and tokens with notebooks.
Secrets are a safe way to share credentials and tokens with notebooks
across your whole team.
They are often used by Smart cells and can be read as
environment variables using the <code>LB_</code> prefix.
</p>
@ -189,7 +190,7 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do
</h2>
<p class="text-gray-700">
File storages are used to store notebooks and their files.
File storages are used to store notebooks and their files across your whole team.
</p>
<.live_component

View file

@ -33,11 +33,11 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupComponent do
<h3 class="font-semibold"><%= @deployment_group.name %></h3>
<%= if @deployment_group.mode == :online do %>
<div class="bg-green-100 text-green-800 text-xs px-2.5 py-0.5 rounded cursor-default">
<%= @deployment_group.mode %>
Online
</div>
<% else %>
<div class="bg-red-100 text-red-800 text-xs px-2.5 py-0.5 rounded cursor-default">
<%= @deployment_group.mode %>
Airgapped
</div>
<% end %>
</div>

View file

@ -123,9 +123,8 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
defp content(assigns) do
~H"""
<div class="flex flex-col gap-4">
<p class="text-gray-700">
You can deploy this app in the cloud using Docker. To do that, configure
the deployment and then use the generated Dockerfile.
<p class="text-gray-700 pb-4">
Choose your deployment settings and then deploy your notebook using the generated Dockerfile.
</p>
<div class="flex gap-12">
@ -158,7 +157,16 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
<.label help={deployment_group_help()}>
Deployment Group
</.label>
<span>No deployment groups available</span>
<span>
None configured
<.link
navigate={~p"/hub/#{@hub.id}/groups/new"}
target="_blank"
class="pl-3 text-blue-600 font-semibold"
>
+ add new
</.link>
</span>
</p>
<% end %>
<% end %>
@ -177,29 +185,107 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
form={f}
disabled={@deployment_group_id != nil}
/>
<AppComponents.docker_config_form_content hub={@hub} form={f} />
<div class="flex flex-col space-y-4">
<.radio_field
label="Deploy"
field={f[:deploy_all]}
options={[
{"false", "Only this notebook"},
{"true", "All notebooks in the current directory"}
]}
/>
<.radio_field
label="Base image"
field={f[:docker_tag]}
options={AppComponents.docker_tag_options()}
/>
</div>
</div>
</.form>
<AppComponents.docker_instructions
hub={@hub}
dockerfile={@dockerfile}
dockerfile_config={apply_changes(@changeset)}
>
<:dockerfile_actions>
<.button
color="gray"
small
type="button"
aria-label="save dockerfile alongside the notebook"
phx-click="save_dockerfile"
phx-target={@myself}
>
<.remix_icon icon="save-line" />
<span>Save alongside notebook</span>
</.button>
</:dockerfile_actions>
</AppComponents.docker_instructions>
<div class="flex flex-col gap-4 pt-6">
<div>
<div class="flex items-end mb-1 gap-1">
<span class="text-sm text-gray-700 font-semibold">Dockerfile</span>
<div class="grow" />
<.button
color="gray"
small
type="button"
aria-label="save dockerfile alongside the notebook"
phx-click="save_dockerfile"
phx-target={@myself}
>
<.remix_icon icon="save-line" />
<span>Save alongside notebook</span>
</.button>
<.button
color="gray"
small
data-tooltip="Copied to clipboard"
type="button"
aria-label="copy to clipboard"
phx-click={
JS.dispatch("lb:clipcopy", to: "#dockerfile-source")
|> JS.transition("tooltip top", time: 2000)
}
>
<.remix_icon icon="clipboard-line" />
<span>Copy source</span>
</.button>
</div>
<.code_preview source_id="dockerfile-source" source={@dockerfile} language="dockerfile" />
</div>
<div class="text-gray-700">
To test the deployment locally, go the the notebook directory, save the Dockerfile, then run:
</div>
<.code_preview
source_id="dockerfile-cmd"
source={
~s'''
docker build -t my-app .
docker run --rm -p 8080:8080 -p 8081:8081 my-app
'''
}
language="text"
/>
<p class="text-gray-700 py-2">
You may additionally perform the following optional steps:
</p>
<ul class="text-gray-700 space-y-3">
<li :if={Hubs.Provider.type(@hub) == "team"} class="flex gap-2">
<div><.remix_icon icon="arrow-right-line" class="text-gray-900" /></div>
<span>
you may remove the default value for <code>TEAMS_KEY</code>
from your Dockerfile and set it as a build argument in your deployment
platform
</span>
</li>
<li :if={apply_changes(@changeset).clustering} class="flex gap-2">
<div><.remix_icon icon="arrow-right-line" class="text-gray-900" /></div>
<span>
you may set <code>LIVEBOOK_SECRET_KEY_BASE</code>
and <code>LIVEBOOK_COOKIE</code>
as runtime environment secrets in your deployment platform, to ensure their
values stay the same across deployments. If you do that, you can remove
the defaults from your Dockerfile
</span>
</li>
<li class="flex gap-2">
<div><.remix_icon icon="arrow-right-line" class="text-gray-900" /></div>
<span>
if you want to debug your deployed notebooks in production, you may
set the <code>LIVEBOOK_PASSWORD</code> environment variable with a
value of at least 12 characters of your choice
</span>
</li>
</ul>
</div>
</div>
"""
end
@ -289,10 +375,15 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
end
defp deployment_group_options(deployment_groups) do
for deployment_group <- [%{name: "none", id: nil}] ++ deployment_groups,
do: {deployment_group.name, deployment_group.id}
[{"none", nil}] ++
for deployment_group <- deployment_groups do
{"#{deployment_group.name} (#{mode(deployment_group.mode)})", deployment_group.id}
end
end
defp mode(:online), do: "online"
defp mode(:offline), do: "airgapped"
defp deployment_group_help() do
"Share deployment credentials, secrets, and configuration with deployment groups."
end

View file

@ -62,13 +62,12 @@ defmodule LivebookWeb.SessionLive.AppInfoComponent do
</h3>
<div class="mt-2 flex flex-col gap-2">
<%!-- TODO: Livebook Teams flow --%>
<.button
color="blue"
patch={
if Livebook.Notebook.AppSettings.valid?(@settings),
do: ~p"/sessions/#{@session.id}/app-docker",
else: ~p"/sessions/#{@session.id}/settings/app?context=app-docker"
do: ~p"/sessions/#{@session.id}/app-teams",
else: ~p"/sessions/#{@session.id}/settings/app?context=app-teams"
}
>
<.remix_icon icon="rocket-line" /> Deploy with Livebook Teams

View file

@ -113,7 +113,7 @@ defmodule LivebookWeb.SessionLive.AppTeamsComponent do
<.label help={deployment_group_help()}>
Deployment Group
</.label>
<span>No deployment groups available</span>
<span>None configured</span>
</p>
<% end %>
<% end %>

View file

@ -328,7 +328,7 @@ defmodule LivebookWeb.Integration.Hub.EditLiveTest do
assert view
|> element("#secrets-form")
|> render_submit(attrs) =~
"You are not authorized to perform this action, make sure you have the access or you are not in a Livebook Agent/Offline instance"
"You are not authorized to perform this action, make sure you have the access and you are not in a Livebook App Server/Offline instance"
refute_receive {:secret_created, ^secret}
refute secret in Livebook.Hubs.get_secrets(hub)
@ -356,7 +356,7 @@ defmodule LivebookWeb.Integration.Hub.EditLiveTest do
assert view
|> element("#file-systems-form")
|> render_submit(attrs) =~
"You are not authorized to perform this action, make sure you have the access or you are not in a Livebook Agent/Offline instance"
"You are not authorized to perform this action, make sure you have the access and you are not in a Livebook App Server/Offline instance"
refute_receive {:file_system_created, %{id: ^id}}
refute file_system in Livebook.Hubs.get_file_systems(hub)

View file

@ -457,7 +457,7 @@ defmodule LivebookWeb.Integration.SessionLiveTest do
{:ok, view, _} = live(conn, ~p"/sessions/#{session.id}/app-docker")
assert render(view) =~ "Deployment Group"
assert render(view) =~ "No deployment groups available"
assert render(view) =~ "None configured"
refute has_element?(view, "#select_deployment_group_form")
end