Implement the Livebook Agent Dockerfile generation (#2481)

This commit is contained in:
Alexandre de Souza 2024-03-10 15:42:09 -03:00 committed by GitHub
parent 0c278bf0c5
commit e30117aca8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 81 additions and 4 deletions

View file

@ -157,6 +157,35 @@ defmodule Livebook.Hubs.Dockerfile do
|> Enum.join("\n") |> Enum.join("\n")
end end
@doc """
Builds Dockerfile definition for Livebook Agent app deployment.
"""
@spec build_agent_dockerfile(config(), Hubs.Provider.t()) :: String.t()
def build_agent_dockerfile(config, hub) do
base_image = Enum.find(Livebook.Config.docker_images(), &(&1.tag == config.docker_tag))
image = """
FROM ghcr.io/livebook-dev/livebook:#{base_image.tag}
"""
image_envs = format_envs(base_image.env)
hub_config = """
# Teams Hub configuration for Livebook Agent deployment
ENV LIVEBOOK_AGENT_NAME ""
ENV LIVEBOOK_TEAMS_KEY "#{hub.teams_key}"
ENV LIVEBOOK_TEAMS_AUTH "online:#{hub.hub_name}:#{hub.org_id}:#{hub.org_key_id}:${LIVEBOOK_AGENT_KEY}"
"""
[
image,
image_envs,
hub_config
]
|> Enum.reject(&is_nil/1)
|> Enum.join("\n")
end
defp format_hub_config("team", config, hub, hub_file_systems, used_secrets) do defp format_hub_config("team", config, hub, hub_file_systems, used_secrets) do
base_env = base_env =
""" """

View file

@ -60,7 +60,8 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
|> assign_new(:config_changeset, fn -> |> assign_new(:config_changeset, fn ->
Hubs.Dockerfile.config_changeset(Hubs.Dockerfile.config_new()) Hubs.Dockerfile.config_changeset(Hubs.Dockerfile.config_new())
end) end)
|> update_dockerfile()} |> update_dockerfile(:airgapped)
|> update_dockerfile(:agent)}
end end
@impl true @impl true
@ -145,6 +146,46 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
<span>Add agent key</span> <span>Add agent key</span>
</.button> </.button>
</div> </div>
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
Agent deployment
</h2>
<p class="text-gray-700">
You can deploy your team notebooks directly to a self-hosted agent instance.
To do that, create an agent in the section above, then start an agent instance
using the Dockerfile below. Once the agent connects to the Livebook Teams server
and it will become available for app deployments.
</p>
<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" />
<.button
color="gray"
small
data-tooltip="Copied to clipboard"
type="button"
aria-label="copy to clipboard"
phx-click={
JS.dispatch("lb:clipcopy", to: "#agent-dockerfile-source")
|> JS.add_class("", transition: {"tooltip top", "", ""}, time: 2000)
}
>
<.remix_icon icon="clipboard-line" />
<span>Copy source</span>
</.button>
</div>
<.code_preview
source_id="agent-dockerfile-source"
source={@agent_dockerfile}
language="dockerfile"
/>
</div>
</div>
</div> </div>
<div class="flex flex-col space-y-4"> <div class="flex flex-col space-y-4">
@ -209,7 +250,7 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
{:noreply, {:noreply,
socket socket
|> assign(config_changeset: changeset) |> assign(config_changeset: changeset)
|> update_dockerfile()} |> update_dockerfile(:airgapped)}
end end
def handle_event("add_agent_key", _, socket) do def handle_event("add_agent_key", _, socket) do
@ -249,9 +290,9 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
Hubs.get_default_hub().id == hub.id Hubs.get_default_hub().id == hub.id
end end
defp update_dockerfile(socket) when socket.assigns.deployment_group == nil, do: socket defp update_dockerfile(socket, _) when socket.assigns.deployment_group == nil, do: socket
defp update_dockerfile(socket) do defp update_dockerfile(socket, :airgapped) do
config = config =
socket.assigns.config_changeset socket.assigns.config_changeset
|> Ecto.Changeset.apply_changes() |> Ecto.Changeset.apply_changes()
@ -278,4 +319,11 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
assign(socket, :dockerfile, dockerfile) assign(socket, :dockerfile, dockerfile)
end end
defp update_dockerfile(%{assigns: %{hub: hub}} = socket, :agent) do
config = Hubs.Dockerfile.config_new()
dockerfile = Hubs.Dockerfile.build_agent_dockerfile(config, hub)
assign(socket, :agent_dockerfile, dockerfile)
end
end end