From 3c98bc35e378730eb417cf65a0ef85734f710640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 13 Jun 2024 17:12:10 +0700 Subject: [PATCH 1/3] Defer distribution boot in releases --- README.md | 3 +-- elixirkit/lib/elixirkit/server.ex | 2 +- lib/livebook.ex | 4 +--- rel/app/env.bat.eex | 20 ++++++++------------ rel/app/env.sh.eex | 23 +++++++++++------------ rel/app/vm.args.eex | 3 ++- rel/server/env.bat.eex | 23 +++++++++-------------- rel/server/env.sh.eex | 30 ++++++++++++++++++------------ 8 files changed, 51 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index ee7f19feb8b..766732b7c4d 100644 --- a/README.md +++ b/README.md @@ -256,8 +256,7 @@ The following environment variables can be used to configure Livebook on boot: * `LIVEBOOK_IP` - sets the ip address to start the web application on. Must be a valid IPv4 or IPv6 address. - * `LIVEBOOK_NODE` - sets the node name for running Livebook in a cluster. Note that - this sets RELEASE_NODE if present when creating a release. + * `LIVEBOOK_NODE` - sets the node name for running Livebook in a cluster. * `LIVEBOOK_PASSWORD` - sets a password that must be used to access Livebook. Must be at least 12 characters. Defaults to token authentication. diff --git a/elixirkit/lib/elixirkit/server.ex b/elixirkit/lib/elixirkit/server.ex index 56caa9e5cca..b1f58e441c8 100644 --- a/elixirkit/lib/elixirkit/server.ex +++ b/elixirkit/lib/elixirkit/server.ex @@ -10,7 +10,7 @@ defmodule ElixirKit.Server do @impl true def init(pid) do port = System.fetch_env!("ELIXIRKIT_PORT") |> String.to_integer() - {:ok, socket} = :gen_tcp.connect('localhost', port, mode: :binary, packet: 4) + {:ok, socket} = :gen_tcp.connect(~c"localhost", port, mode: :binary, packet: 4) {:ok, %{pid: pid, socket: socket}} end diff --git a/lib/livebook.ex b/lib/livebook.ex index 7052f8c1e85..e207340d983 100644 --- a/lib/livebook.ex +++ b/lib/livebook.ex @@ -203,9 +203,7 @@ defmodule Livebook do config :livebook, :cookie, - Livebook.Config.cookie!("LIVEBOOK_COOKIE") || - Livebook.Config.cookie!("RELEASE_COOKIE") || - Livebook.Utils.random_cookie() + Livebook.Config.cookie!("LIVEBOOK_COOKIE") || Livebook.Utils.random_cookie() # TODO: remove in v1.0 if System.get_env("LIVEBOOK_DISTRIBUTION") == "sname" do diff --git a/rel/app/env.bat.eex b/rel/app/env.bat.eex index 439c83a65f5..1c575f7dade 100644 --- a/rel/app/env.bat.eex +++ b/rel/app/env.bat.eex @@ -6,19 +6,13 @@ if not defined LIVEBOOK_EPMDLESS set LIVEBOOK_EPMDLESS=true if "!LIVEBOOK_EPMDLESS!"=="1" goto epmdless if "!LIVEBOOK_EPMDLESS!"=="true" goto epmdless goto continue - :epmdless set ELIXIR_ERL_OPTIONS=!ELIXIR_ERL_OPTIONS! -epmd_module Elixir.Livebook.EPMD -start_epmd false -erl_epmd_port 0 - :continue -for /f "skip=1" %%X in ('wmic os get localdatetime') do if not defined TIMESTAMP set TIMESTAMP=%%X - -set RELEASE_DISTRIBUTION="name" -if defined LIVEBOOK_NODE set RELEASE_NODE=!LIVEBOOK_NODE! -if not defined RELEASE_NODE set RELEASE_NODE=livebook-app-!TIMESTAMP:~8,6!-!RANDOM! +set RELEASE_MODE="interactive" +set RELEASE_DISTRIBUTION="none" -set RELEASE_MODE=interactive set MIX_ARCHIVES=!RELEASE_ROOT!\vendor\archives set MIX_REBAR3=!RELEASE_ROOT!\vendor\rebar3 if not defined LIVEBOOK_SHUTDOWN_ENABLED set LIVEBOOK_SHUTDOWN_ENABLED=true @@ -26,10 +20,12 @@ set LIVEBOOK_DESKTOP=true if not defined LIVEBOOK_PORT (set LIVEBOOK_PORT=0) set PATH=!RELEASE_ROOT!\vendor\otp\erts-<%= @release.erts_version%>\bin;!RELEASE_ROOT!\vendor\otp\bin;!RELEASE_ROOT!\vendor\elixir\bin;!PATH! -set cookie_path=!RELEASE_ROOT!\releases\COOKIE -if not exist %cookie_path% ( - :: '| set /p=""' is so that we don't add ' \r\n' to the cookie - echo | set /p="cookie-!TIMESTAMP:~0,11!-!RANDOM!" > %cookie_path% +if defined LIVEBOOK_NODE set RELEASE_NODE=!LIVEBOOK_NODE! +if defined LIVEBOOK_COOKIE set RELEASE_COOKIE=!LIVEBOOK_COOKIE! + +if not defined RELEASE_COOKIE ( + for /f "skip=1" %%X in ('wmic os get localdatetime') do if not defined TIMESTAMP set TIMESTAMP=%%X + set RELEASE_COOKIE=cookie-!TIMESTAMP:~0,11!-!RANDOM! ) cd !HOMEDRIVE!!HOMEPATH! diff --git a/rel/app/env.sh.eex b/rel/app/env.sh.eex index eaebd16681f..51a377f521b 100644 --- a/rel/app/env.sh.eex +++ b/rel/app/env.sh.eex @@ -2,25 +2,24 @@ if [ -f "$HOME/.livebookdesktop.sh" ]; then . "$HOME/.livebookdesktop.sh" fi -export RELEASE_DISTRIBUTION="name" -export RELEASE_NODE=${LIVEBOOK_NODE:-${RELEASE_NODE:-"livebook-app-$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)"}} -export RELEASE_MODE=interactive +export LIVEBOOK_EPMDLESS=${LIVEBOOK_EPMDLESS:-true} +if [ "$LIVEBOOK_EPMDLESS" = "true" ] || [ "$LIVEBOOK_EPMDLESS" = "1" ]; then + export ELIXIR_ERL_OPTIONS="${ELIXIR_ERL_OPTIONS} -epmd_module Elixir.Livebook.EPMD -start_epmd false -erl_epmd_port 0" +fi + +export RELEASE_MODE="interactive" +export RELEASE_DISTRIBUTION="none" + export MIX_ARCHIVES="${RELEASE_ROOT}/vendor/archives" export MIX_REBAR3="${RELEASE_ROOT}/vendor/rebar3" -export LIVEBOOK_EPMDLESS=${LIVEBOOK_EPMDLESS:-true} export LIVEBOOK_SHUTDOWN_ENABLED=${LIVEBOOK_SHUTDOWN_ENABLED:-true} export LIVEBOOK_DESKTOP=true [ -z "$LIVEBOOK_PORT" ] && export LIVEBOOK_PORT=0 export PATH="$RELEASE_ROOT/vendor/otp/erts-<%= @release.erts_version%>/bin:$RELEASE_ROOT/vendor/otp/bin:$RELEASE_ROOT/vendor/elixir/bin:$PATH" -if [ "$LIVEBOOK_EPMDLESS" = "true" ] || [ "$LIVEBOOK_EPMDLESS" = "1" ]; then - export ELIXIR_ERL_OPTIONS="${ELIXIR_ERL_OPTIONS} -epmd_module Elixir.Livebook.EPMD -start_epmd false -erl_epmd_port 0" -fi +if [ ! -z "${LIVEBOOK_NODE}" ]; then export RELEASE_NODE=${LIVEBOOK_NODE}; fi +if [ ! -z "${LIVEBOOK_COOKIE}" ]; then export RELEASE_COOKIE=${LIVEBOOK_COOKIE}; fi -cookie_path="${RELEASE_ROOT}/releases/COOKIE" -if [ ! -f $cookie_path ]; then - RELEASE_COOKIE=$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) - echo "$RELEASE_COOKIE" > "$cookie_path" || export RELEASE_COOKIE -fi +export RELEASE_COOKIE="${RELEASE_COOKIE:-$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)}" cd $HOME diff --git a/rel/app/vm.args.eex b/rel/app/vm.args.eex index 67880f479c1..abd39f5ab75 100644 --- a/rel/app/vm.args.eex +++ b/rel/app/vm.args.eex @@ -1,2 +1,3 @@ # Disable busy waiting so that we don't waste resources -+sbwt none +sbwtdcpu none +sbwtdio none +# Limit the maximal number of ports for the same reason ++sbwt none +sbwtdcpu none +sbwtdio none +Q 65536 diff --git a/rel/server/env.bat.eex b/rel/server/env.bat.eex index 3def5c56bb8..f6677c2918c 100644 --- a/rel/server/env.bat.eex +++ b/rel/server/env.bat.eex @@ -5,22 +5,17 @@ if exist "!RELEASE_ROOT!\user\env.bat" ( if "!LIVEBOOK_EPMDLESS!"=="1" goto epmdless if "!LIVEBOOK_EPMDLESS!"=="true" goto epmdless goto continue - :epmdless set ELIXIR_ERL_OPTIONS=!ELIXIR_ERL_OPTIONS! -epmd_module Elixir.Livebook.EPMD -start_epmd false -erl_epmd_port 0 - :continue -set RELEASE_MODE=interactive -if defined LIVEBOOK_NODE set RELEASE_NODE="!LIVEBOOK_NODE!" -if not defined RELEASE_NODE set RELEASE_NODE=livebook_server -set RELEASE_DISTRIBUTION="name" -if defined LIVEBOOK_COOKIE set RELEASE_COOKIE="!LIVEBOOK_COOKIE!" -set cookie_path="!RELEASE_ROOT!\releases\COOKIE" -if not exist %cookie_path% ( - if not defined RELEASE_COOKIE ( - for /f "skip=1" %%X in ('wmic os get localdatetime') do if not defined TIMESTAMP set TIMESTAMP=%%X - :: '| set /p=""' is so that we don't add ' \r\n' to the cookie - echo | set /p="cookie-!TIMESTAMP:~0,11!-!RANDOM!" > %cookie_path% - ) +set RELEASE_MODE="interactive" +set RELEASE_DISTRIBUTION="none" + +if defined LIVEBOOK_NODE set RELEASE_NODE=!LIVEBOOK_NODE! +if defined LIVEBOOK_COOKIE set RELEASE_COOKIE=!LIVEBOOK_COOKIE! + +if not defined RELEASE_COOKIE ( + for /f "skip=1" %%X in ('wmic os get localdatetime') do if not defined TIMESTAMP set TIMESTAMP=%%X + set RELEASE_COOKIE=cookie-!TIMESTAMP:~0,11!-!RANDOM! ) diff --git a/rel/server/env.sh.eex b/rel/server/env.sh.eex index 6cc564e6e36..8a0969572e6 100644 --- a/rel/server/env.sh.eex +++ b/rel/server/env.sh.eex @@ -1,26 +1,32 @@ -NODE_DEFAULT="livebook_server" - if [ "$LIVEBOOK_CLUSTER" = "fly" ]; then export ERL_AFLAGS="-proto_dist inet6_tcp" export LIVEBOOK_CLUSTER="dns:${FLY_APP_NAME}.internal" - NODE_DEFAULT="${FLY_APP_NAME}-${FLY_IMAGE_REF##*-}@${FLY_PRIVATE_IP}" + if [ ! -z "${LIVEBOOK_NODE}" ]; + then export LIVEBOOK_NODE="${FLY_APP_NAME}-${FLY_IMAGE_REF##*-}@${FLY_PRIVATE_IP}"; + fi fi if [ -f "${RELEASE_ROOT}/user/env.sh" ]; then . "${RELEASE_ROOT}/user/env.sh" fi -export RELEASE_MODE=interactive -export RELEASE_NODE=${LIVEBOOK_NODE:-${RELEASE_NODE:-${NODE_DEFAULT}}} -export RELEASE_DISTRIBUTION="name" - if [ "$LIVEBOOK_EPMDLESS" = "true" ] || [ "$LIVEBOOK_EPMDLESS" = "1" ]; then export ELIXIR_ERL_OPTIONS="${ELIXIR_ERL_OPTIONS} -epmd_module Elixir.Livebook.EPMD -start_epmd false -erl_epmd_port 0" fi +export RELEASE_MODE="interactive" +export RELEASE_DISTRIBUTION="none" + +# Mirror these values, so that it is easier to use "bin/release rpc", +# though it still requires setting RELEASE_DISTRIBUTION=name +if [ ! -z "${LIVEBOOK_NODE}" ]; then export RELEASE_NODE=${LIVEBOOK_NODE}; fi if [ ! -z "${LIVEBOOK_COOKIE}" ]; then export RELEASE_COOKIE=${LIVEBOOK_COOKIE}; fi -cookie_path="${RELEASE_ROOT}/releases/COOKIE" -if [ ! -f $cookie_path ] && [ -z "$RELEASE_COOKIE" ]; then - RELEASE_COOKIE=$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) - echo "$RELEASE_COOKIE" > "$cookie_path" || export RELEASE_COOKIE -fi + +# We remove the COOKIE file when assembling the release, because we +# don't want to share the same cookie across users. The Elixir release +# script attempts to read from that file, which would fail, therefore +# we need to set it here. Also note that there is a very tiny time gap +# between we start distribution and set the cookie during application +# boot, so we specifically want the temporary node cookie to be random, +# rather than a fixed value. +export RELEASE_COOKIE="${RELEASE_COOKIE:-$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)}" From 6fddce878754dcefe73e2a7236572c9dcbca0801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 13 Jun 2024 22:21:23 +0700 Subject: [PATCH 2/3] Up --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 766732b7c4d..565cc23127b 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,9 @@ The following environment variables can be used to configure Livebook on boot: Must be a valid IPv4 or IPv6 address. * `LIVEBOOK_NODE` - sets the node name for running Livebook in a cluster. + Note that Livebook always runs using long names distrivution, so the + node host name must use a fully qualified domain name (FQDN) or an IP + address. * `LIVEBOOK_PASSWORD` - sets a password that must be used to access Livebook. Must be at least 12 characters. Defaults to token authentication. From 122891a8932b54a2fe3871a96d389938c57c2e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 13 Jun 2024 22:59:27 +0700 Subject: [PATCH 3/3] Up --- rel/server/env.sh.eex | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rel/server/env.sh.eex b/rel/server/env.sh.eex index 8a0969572e6..7b2a03d0807 100644 --- a/rel/server/env.sh.eex +++ b/rel/server/env.sh.eex @@ -25,8 +25,9 @@ if [ ! -z "${LIVEBOOK_COOKIE}" ]; then export RELEASE_COOKIE=${LIVEBOOK_COOKIE}; # We remove the COOKIE file when assembling the release, because we # don't want to share the same cookie across users. The Elixir release # script attempts to read from that file, which would fail, therefore -# we need to set it here. Also note that there is a very tiny time gap -# between we start distribution and set the cookie during application -# boot, so we specifically want the temporary node cookie to be random, -# rather than a fixed value. +# we need to set it here. Also there is a very tiny time gap between we +# start distribution and set the cookie during application boot, so we +# specifically want the temporary node cookie to be random, rather than +# a fixed value. Note that this value is overriden on boot, so other +# than being the initial node cookie, we don't really use it. export RELEASE_COOKIE="${RELEASE_COOKIE:-$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)}"