mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-12-18 22:21:32 +08:00
Detect if Livebook or another application is running on the given port (#530)
* Detect if Livebook or another application is running on the given port * Use json/2 * Print error when the port is taken
This commit is contained in:
parent
01c079a697
commit
2a338b6b83
3 changed files with 83 additions and 17 deletions
|
|
@ -53,24 +53,29 @@ defmodule LivebookCLI.Server do
|
||||||
config_entries = opts_to_config(opts, [])
|
config_entries = opts_to_config(opts, [])
|
||||||
put_config_entries(config_entries)
|
put_config_entries(config_entries)
|
||||||
|
|
||||||
case start_server() do
|
port = Application.get_env(:livebook, LivebookWeb.Endpoint)[:http][:port]
|
||||||
:ok ->
|
base_url = "http://localhost:#{port}"
|
||||||
if opts[:open] do
|
|
||||||
browser_open(LivebookWeb.Endpoint.access_url())
|
case check_endpoint_availability(base_url) do
|
||||||
|
:livebook_running ->
|
||||||
|
IO.puts("Livebook already running on #{base_url}")
|
||||||
|
open_from_options(base_url, opts)
|
||||||
|
|
||||||
|
:taken ->
|
||||||
|
print_error(
|
||||||
|
"Another application is already running on port #{port}." <>
|
||||||
|
" Either ensure this port is free or specify a different port using the --port option"
|
||||||
|
)
|
||||||
|
|
||||||
|
:available ->
|
||||||
|
case start_server() do
|
||||||
|
:ok ->
|
||||||
|
open_from_options(LivebookWeb.Endpoint.access_url(), opts)
|
||||||
|
Process.sleep(:infinity)
|
||||||
|
|
||||||
|
:error ->
|
||||||
|
print_error("Livebook failed to start")
|
||||||
end
|
end
|
||||||
|
|
||||||
if opts[:open_new] do
|
|
||||||
LivebookWeb.Endpoint.access_url()
|
|
||||||
|> URI.parse()
|
|
||||||
|> Map.update!(:path, &((&1 || "/") <> "explore/notebooks/new"))
|
|
||||||
|> URI.to_string()
|
|
||||||
|> browser_open()
|
|
||||||
end
|
|
||||||
|
|
||||||
Process.sleep(:infinity)
|
|
||||||
|
|
||||||
:error ->
|
|
||||||
IO.ANSI.format([:red, "Livebook failed to start"]) |> IO.puts()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -86,6 +91,26 @@ defmodule LivebookCLI.Server do
|
||||||
|> Application.put_all_env(persistent: true)
|
|> Application.put_all_env(persistent: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp check_endpoint_availability(base_url) do
|
||||||
|
Application.ensure_all_started(:inets)
|
||||||
|
|
||||||
|
health_url = append_path(base_url, "health")
|
||||||
|
|
||||||
|
case Livebook.Utils.HTTP.request(:get, health_url) do
|
||||||
|
{:ok, status, _headers, body} ->
|
||||||
|
with 200 <- status,
|
||||||
|
{:ok, body} <- Jason.decode(body),
|
||||||
|
%{"application" => "livebook"} <- body do
|
||||||
|
:livebook_running
|
||||||
|
else
|
||||||
|
_ -> :taken
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, _error} ->
|
||||||
|
:available
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp start_server() do
|
defp start_server() do
|
||||||
# We configure the endpoint with `server: true`,
|
# We configure the endpoint with `server: true`,
|
||||||
# so it's gonna start listening
|
# so it's gonna start listening
|
||||||
|
|
@ -95,6 +120,18 @@ defmodule LivebookCLI.Server do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp open_from_options(base_url, opts) do
|
||||||
|
if opts[:open] do
|
||||||
|
browser_open(base_url)
|
||||||
|
end
|
||||||
|
|
||||||
|
if opts[:open_new] do
|
||||||
|
base_url
|
||||||
|
|> append_path("explore/notebooks/new")
|
||||||
|
|> browser_open()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@switches [
|
@switches [
|
||||||
cookie: :string,
|
cookie: :string,
|
||||||
default_runtime: :string,
|
default_runtime: :string,
|
||||||
|
|
@ -184,4 +221,15 @@ defmodule LivebookCLI.Server do
|
||||||
|
|
||||||
System.cmd(cmd, args)
|
System.cmd(cmd, args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp append_path(url, path) do
|
||||||
|
url
|
||||||
|
|> URI.parse()
|
||||||
|
|> Map.update!(:path, &((&1 || "/") <> path))
|
||||||
|
|> URI.to_string()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp print_error(message) do
|
||||||
|
IO.ANSI.format([:red, message]) |> IO.puts()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
12
lib/livebook_web/controllers/health_controller.ex
Normal file
12
lib/livebook_web/controllers/health_controller.ex
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
defmodule LivebookWeb.HealthController do
|
||||||
|
use LivebookWeb, :controller
|
||||||
|
|
||||||
|
def index(conn, _params) do
|
||||||
|
version = Application.spec(:livebook, :vsn) |> List.to_string()
|
||||||
|
|
||||||
|
json(conn, %{
|
||||||
|
"application" => "livebook",
|
||||||
|
"version" => version
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -52,6 +52,12 @@ defmodule LivebookWeb.Router do
|
||||||
home_app: {"Livebook", :livebook}
|
home_app: {"Livebook", :livebook}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope "/", LivebookWeb do
|
||||||
|
pipe_through :browser
|
||||||
|
|
||||||
|
get "/health", HealthController, :index
|
||||||
|
end
|
||||||
|
|
||||||
scope "/authenticate", LivebookWeb do
|
scope "/authenticate", LivebookWeb do
|
||||||
pipe_through :browser
|
pipe_through :browser
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue