Use woodpecker-ci to deploy binaries to the R2 object storage. Use multi-target builds to deploy multiple binaries for one or more CPU architectures. Now the installation script lives on the root of the repo, and it is more complete checking the machine's requirements, operating system and cpu architecture.
136 lines
2.8 KiB
Elixir
136 lines
2.8 KiB
Elixir
defmodule Prymn.Servers do
|
|
@moduledoc """
|
|
The Servers context.
|
|
"""
|
|
|
|
import Ecto.Query, warn: false
|
|
alias Prymn.Repo
|
|
|
|
alias Prymn.Servers.Server
|
|
|
|
@doc """
|
|
Returns the list of servers.
|
|
|
|
## Examples
|
|
|
|
iex> list_servers()
|
|
[%Server{}, ...]
|
|
|
|
"""
|
|
def list_servers do
|
|
Repo.all(Server)
|
|
end
|
|
|
|
@doc """
|
|
Gets a single server.
|
|
|
|
Raises `Ecto.NoResultsError` if the Server does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_server!(123)
|
|
%Server{}
|
|
|
|
iex> get_server!(456)
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_server!(id), do: Repo.get!(Server, id)
|
|
|
|
@doc """
|
|
Get a single server by its IP.
|
|
"""
|
|
@spec get_server_by_ip!(String.t()) :: %Server{}
|
|
def get_server_by_ip!(ip), do: Repo.get_by!(Server, public_ip: ip)
|
|
|
|
@doc """
|
|
|
|
Start a new server connection with the app.
|
|
"""
|
|
def create_server(attrs \\ %{}) do
|
|
# Create a unique registration token
|
|
%Server{registration_token: :crypto.strong_rand_bytes(16)}
|
|
|> Server.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Registers a server using a registration token.
|
|
"""
|
|
def register_server(token, public_ip) do
|
|
with true <- :inet.is_ip_address(public_ip),
|
|
{:ok, token} <- Base.decode64(token) do
|
|
public_ip_string =
|
|
public_ip
|
|
|> :inet.ntoa()
|
|
|> to_string()
|
|
|
|
from(s in Server, where: s.registration_token == ^token, select: s)
|
|
|> Repo.one!()
|
|
|> update_server(%{public_ip: public_ip_string, status: :registered})
|
|
else
|
|
false -> {:error, :invalid_ip}
|
|
:error -> {:error, :bad_token}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Updates a server.
|
|
|
|
## Examples
|
|
|
|
iex> update_server(server, %{field: new_value})
|
|
{:ok, %Server{}}
|
|
|
|
iex> update_server(server, %{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def update_server(%Server{} = server, attrs) do
|
|
server
|
|
|> Server.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
@doc """
|
|
Deletes a server.
|
|
|
|
## Examples
|
|
|
|
iex> delete_server(server)
|
|
{:ok, %Server{}}
|
|
|
|
iex> delete_server(server)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def delete_server(%Server{} = server) do
|
|
Repo.delete(server)
|
|
end
|
|
|
|
@doc """
|
|
Returns an `%Ecto.Changeset{}` for tracking server changes.
|
|
|
|
## Examples
|
|
|
|
iex> change_server(server)
|
|
%Ecto.Changeset{data: %Server{}}
|
|
|
|
"""
|
|
def change_server(%Server{} = server, attrs \\ %{}) do
|
|
Server.changeset(server, attrs)
|
|
end
|
|
|
|
@doc """
|
|
Returns a string containing the command that needs to be executed to the
|
|
remote server in order to register it to the backend.
|
|
"""
|
|
@spec create_setup_command(%Server{}) :: String.t()
|
|
def create_setup_command(%Server{registration_token: token}) do
|
|
token
|
|
|> Base.encode64()
|
|
|> then(fn token ->
|
|
"curl -sSfL " <> PrymnWeb.Endpoint.url() <> "/install | sh -s " <> token
|
|
end)
|
|
end
|
|
end
|