Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defer distribution boot in releases #2648

Merged
merged 3 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,10 @@ 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.
jonatanklosko marked this conversation as resolved.
Show resolved Hide resolved
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.
Expand Down
2 changes: 1 addition & 1 deletion elixirkit/lib/elixirkit/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 1 addition & 3 deletions lib/livebook.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josevalim we are no longer respecting RELEASE_NODE, because the Elixir release script defaults its value to release name, which we don't want to use. I think we should ignore RELEASE_COOKIE also for consistency. I think it makes sense to expect the configuration to happen via LIVEBOOK_* env vars.


# TODO: remove in v1.0
if System.get_env("LIVEBOOK_DISTRIBUTION") == "sname" do
Expand Down
20 changes: 8 additions & 12 deletions rel/app/env.bat.eex
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,26 @@ 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
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!
23 changes: 11 additions & 12 deletions rel/app/env.sh.eex
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion rel/app/vm.args.eex
Original file line number Diff line number Diff line change
@@ -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
23 changes: 9 additions & 14 deletions rel/server/env.bat.eex
Original file line number Diff line number Diff line change
Expand Up @@ -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!
)
31 changes: 19 additions & 12 deletions rel/server/env.sh.eex
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FTR we used to attempt to write the random cookie to a file and respect RELEASE_COOKIE, such that the cookie was the same on subsequent boots. This was necessary because in the past Livebook Desktop was calling bin/release rpc and so it had to use the same cookie. We no longer do that though, so I simplified the code to no longer write the file.


# 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 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)}"
Loading