From e30117aca8cb0ef50868b108a43704490ba04eda Mon Sep 17 00:00:00 2001 From: Alexandre de Souza Date: Sun, 10 Mar 2024 15:42:09 -0300 Subject: [PATCH] Implement the Livebook Agent Dockerfile generation (#2481) --- lib/livebook/hubs/dockerfile.ex | 29 ++++++++++ .../live/hub/teams/deployment_group_live.ex | 56 +++++++++++++++++-- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/lib/livebook/hubs/dockerfile.ex b/lib/livebook/hubs/dockerfile.ex index 1d77d7b53..f1cdeecb9 100644 --- a/lib/livebook/hubs/dockerfile.ex +++ b/lib/livebook/hubs/dockerfile.ex @@ -157,6 +157,35 @@ defmodule Livebook.Hubs.Dockerfile do |> Enum.join("\n") 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 base_env = """ diff --git a/lib/livebook_web/live/hub/teams/deployment_group_live.ex b/lib/livebook_web/live/hub/teams/deployment_group_live.ex index d276455c5..b30e57516 100644 --- a/lib/livebook_web/live/hub/teams/deployment_group_live.ex +++ b/lib/livebook_web/live/hub/teams/deployment_group_live.ex @@ -60,7 +60,8 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do |> assign_new(:config_changeset, fn -> Hubs.Dockerfile.config_changeset(Hubs.Dockerfile.config_new()) end) - |> update_dockerfile()} + |> update_dockerfile(:airgapped) + |> update_dockerfile(:agent)} end @impl true @@ -145,6 +146,46 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do Add agent key + +

+ Agent deployment +

+ +

+ 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. +

+ +
+
+
+ Dockerfile +
+ <.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" /> + Copy source + +
+ + <.code_preview + source_id="agent-dockerfile-source" + source={@agent_dockerfile} + language="dockerfile" + /> +
+
@@ -209,7 +250,7 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do {:noreply, socket |> assign(config_changeset: changeset) - |> update_dockerfile()} + |> update_dockerfile(:airgapped)} end 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 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 = socket.assigns.config_changeset |> Ecto.Changeset.apply_changes() @@ -278,4 +319,11 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do assign(socket, :dockerfile, dockerfile) 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