defmodule PrymnWeb.ServerLive.Show do use PrymnWeb, :live_view require Logger alias Prymn.{Agents, Servers, Messaging} @impl true def mount(_params, _session, socket) do # TODO: A more lightweight call instead of listing all data? servers = Servers.list_servers() {:ok, assign(socket, :servers, servers)} end @impl true def render(assigns) do ~H"""
<.dropdown title="Select a different server"> <:button variant="tertiary">Server <%= @server.name %> <:item :for={server <- Enum.filter(@servers, &(&1.id != @server.id))} patch={~p"/servers/#{server}"} > <%= server.name %> <.icon class="h-4 w-4" name="hero-pencil-solid" /> <.indicator message="test" />
<.dropdown> <:button variant="tertiary" size="sm">Quick actions <:item> Test New App
<%= @server.public_ip %>

Connect to your server using root credentials and execute the following command:

# <%= @registration_command %>
<.input type="checkbox" name="dry_run" value={@dry_run} label="Enable dry-run operations" />
<.live_component id={"system_info-#{@server.name}"} module={PrymnWeb.SystemInfo} agent={assigns[:agent]} />

System

Updates: <%= 0 %> pending updates. Update now

<%= output %>

Terminal

<.live_component id="terminal" module={PrymnWeb.Terminal} agent={@agent} />
<.back navigate={~p"/servers"}>Back to servers
""" end @impl true def handle_params(%{"id" => id}, _, socket) do server = Servers.get_server!(id) agent = Agents.from_server(server) {:noreply, socket |> assign(:page_title, server.name) |> assign(:server, server) |> assign(:agent, agent) |> assign(:dry_run, false) |> assign(:update_output, []) # TODO: Do not assign this to the socket - instead generate it in the HTML |> assign(:registration_command, Servers.create_setup_command(server))} end @impl true def handle_info(%Agents.Agent{} = agent, socket) do {:noreply, assign(socket, :agent, agent)} end def handle_info(%Messaging.Messages.TerminalOutput{output: output}, socket) do send_update(PrymnWeb.Terminal, id: "terminal", data: output) {:noreply, socket} end # @impl true # def handle_info(%PrymnProto.Prymn.SysUpdateResponse{} = response, socket) do # output = String.split(response.output, "\n") # socket = assign(socket, :update_output, output) # {:noreply, socket} # end # def handle_info(%Agents.Health{host: host} = health, socket) do # socket = # if host == socket.assigns.server.public_ip, # do: assign(socket, :health, health), # else: socket # {:noreply, socket} # end @impl true def handle_event("system_update", _params, socket) do # server_name = get_in(socket.assigns, [:server, Access.key(:name)]) # pid = self() # if agent = socket.assigns[:agent] do # # TODO: This is ugly # Task.start_link(fn -> # Agents.sys_update(agent, %{dry_run: socket.assigns.dry_run}) # |> Stream.each(fn # {:ok, msg} -> send(pid, msg) # {:error, error} -> Logger.error("error during system update call: #{inspect(error)}") # end) # |> Enum.to_list() # end) # put_flash(socket, :info, "Started a system update on server #{server_name}.") # else # put_flash(socket, :error, "Could not perform the update.") # end {:noreply, socket} end def handle_event("edit_server_name", %{"name" => name}, socket) do server = socket.assigns.server |> Servers.update_server(%{"name" => name}) |> case do {:ok, server} -> server {:error, _} -> raise "Oops" end {:noreply, assign(socket, :server, server)} end def handle_event("change_dry_run", %{"dry_run" => enabled}, socket) do enabled = (enabled == "true" && true) || false {:noreply, assign(socket, :dry_run, enabled)} end defp show_edit_server_name() do JS.hide(to: "#server-name") |> JS.show(to: "#server-name-edit", display: "flex") |> JS.focus_first(to: "#server-name-edit") end defp submit_edit_server_name() do JS.push("edit_server_name") |> JS.hide() |> JS.show(to: "#server-name", display: "flex") end defp indicator(assigns) do ~H""" <%= case @message do %> <% "Connected" -> %> <% "Disconnected" -> %> <% _ -> %> <% end %> """ end end