defmodule LivebookWeb.SettingsLive.AddFileSystemComponent do use LivebookWeb, :live_component alias Livebook.FileSystem @impl true def mount(socket) do {:ok, assign(socket, data: empty_data(), error_message: nil)} end @impl true def render(assigns) do ~H"""

Add file system

Configure an AWS S3 bucket as a drop in replacement of the regular file system. Many storage services offer an S3-compatible API, so you can use those as well. One such service is Storj and they offer free storage.

Note that any other user of your Livebook could theoretically extract the credentials, so make sure to properly limit their access to this specific bucket.

<%= if @error_message do %>
<%= @error_message %>
<% end %> <.form let={f} for={:data} phx-target={@myself} phx-submit="add" phx-change="validate" autocomplete="off" spellcheck="false">
Bucket URL
<%= text_input f, :bucket_url, value: @data["bucket_url"], class: "input", placeholder: "https://s3.[region].amazonaws.com/[bucket]" %>
Access Key ID
<.with_password_toggle id="access-key"> <%= text_input f, :access_key_id, value: @data["access_key_id"], class: "input", type: "password" %>
Secret Access Key
<.with_password_toggle id="secret-access-key"> <%= text_input f, :secret_access_key, value: @data["secret_access_key"], class: "input", type: "password" %>
<%= live_patch "Cancel", to: @return_to, class: "button button-outlined-gray" %>
""" end @impl true def handle_event("validate", %{"data" => data}, socket) do {:noreply, assign(socket, :data, data)} end def handle_event("add", %{"data" => data}, socket) do file_system = data_to_file_system(data) default_dir = FileSystem.File.new(file_system) case FileSystem.File.list(default_dir) do {:ok, _} -> file_systems = Livebook.Config.append_file_system(file_system) send(self(), {:file_systems_updated, file_systems}) {:noreply, push_patch(socket, to: socket.assigns.return_to)} {:error, message} -> {:noreply, assign(socket, error_message: "Connection test failed: " <> message)} end end defp empty_data() do %{"bucket_url" => "", "access_key_id" => "", "secret_access_key" => ""} end defp data_valid?(data) do Livebook.Utils.valid_url?(data["bucket_url"]) and data["access_key_id"] != "" and data["secret_access_key"] != "" end defp data_to_file_system(data) do FileSystem.S3.new(data["bucket_url"], data["access_key_id"], data["secret_access_key"]) end end