Current section
Files
Jump to
Current section
Files
lib/fly_machine_client/machines.ex
defmodule FlyMachineClient.Machines do
@moduledoc """
Module for managing machines on Fly.io.
"""
import FlyMachineClient.Helpers
@update_machine_options [
app_name: [type: :string, required: true],
machine_id: [type: :string, required: true],
config: [type: :map, required: false],
name: [type: :string, required: false],
region: [type: :string, required: false],
image: [type: :string, required: false],
env: [type: :map, required: false],
services: [type: :list, required: false],
metadata: [type: :map, required: false]
]
@doc """
Lists all machines for a given app.
## Parameters
- app_name: The name of the app to list machines for.
- opts: Optional. Additional options for the request.
## Returns
{:ok, machines} on success, where machines is a list of machine data.
{:error, error()} on failure.
"""
@spec list_machines(String.t(), FlyMachineClient.options()) :: FlyMachineClient.response()
def list_machines(app_name, opts \\ []) do
client = FlyMachineClient.new(opts)
client |> Tesla.get("/apps/#{app_name}/machines") |> handle_request(:list_machines)
end
@doc """
Gets details of a specific machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to retrieve.
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the machine data.
{:error, error()} on failure.
"""
@spec get_machine(String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def get_machine(app_name, machine_id, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.get("/apps/#{app_name}/machines/#{machine_id}")
|> handle_request(:get_machine)
end
@doc """
Creates a new machine in a Fly.io app.
## Parameters
- params: A map containing the machine creation parameters:
- app_name: The name of the app to create the machine in (required)
- name: The name for the machine (optional)
- region: The region to deploy the machine to (optional)
- config: Machine configuration map (required)
- image: Docker image to use (required)
- env: Environment variables map (optional)
- services: List of services (optional)
- metadata: Metadata map (optional)
- opts: Optional list of options
## Returns
{:ok, machine} on success where machine is the created machine data
{:error, error} on failure
"""
@spec create_machine(map(), FlyMachineClient.options()) :: FlyMachineClient.response()
def create_machine(params, opts \\ []) do
client = FlyMachineClient.new(opts)
app_name = Map.get(params, :app_name)
client
|> Tesla.post("/apps/#{app_name}/machines", params)
|> handle_request(:create_machine)
end
@doc """
Updates an existing machine in a Fly.io app.
## Parameters
- params: A map containing the machine update parameters:
- app_name: The name of the app containing the machine (required)
- machine_id: The ID of the machine to update (required)
- name: New name for the machine (optional)
- region: New region for the machine (optional)
- config: Updated machine configuration map (optional)
- image: New Docker image to use (optional)
- env: Updated environment variables map (optional)
- services: Updated list of services (optional)
- metadata: Updated metadata map (optional)
- opts: Optional list of options
## Returns
{:ok, machine} on success where machine is the updated machine data
{:error, error} on failure
"""
@spec update_machine(map(), FlyMachineClient.options()) :: FlyMachineClient.response()
def update_machine(params, opts \\ []) do
client = FlyMachineClient.new(opts)
with {:ok, validated_params} <- validate_params(params, @update_machine_options) do
app_name = Map.get(validated_params, :app_name)
machine_id = Map.get(validated_params, :machine_id)
update_params = Map.drop(validated_params, [:app_name, :machine_id])
client
|> Tesla.patch("/apps/#{app_name}/machines/#{machine_id}", update_params)
|> handle_request(:update_machine)
end
end
@doc """
Destroys (deletes) a machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to destroy.
- opts: Optional. Additional options for the request.
## Returns
{:ok, nil} on success.
{:error, error()} on failure.
"""
@spec destroy_machine(String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def destroy_machine(app_name, machine_id, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.delete("/apps/#{app_name}/machines/#{machine_id}")
|> handle_request(:destroy_machine)
end
@doc """
Restarts a machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to restart.
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the restarted machine data.
{:error, error()} on failure.
"""
@spec restart_machine(String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def restart_machine(app_name, machine_id, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.post("/apps/#{app_name}/machines/#{machine_id}/restart", %{})
|> handle_request(:restart_machine)
end
@doc """
Sends a signal to a machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to signal.
- signal: The signal to send (e.g., "SIGINT", "SIGTERM").
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the updated machine data.
{:error, error()} on failure.
"""
@spec signal_machine(String.t(), String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def signal_machine(app_name, machine_id, signal, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.post("/apps/#{app_name}/machines/#{machine_id}/signal", %{signal: signal})
|> handle_request(:signal_machine)
end
@doc """
Starts a stopped machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to start.
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the started machine data.
{:error, error()} on failure.
"""
@spec start_machine(String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def start_machine(app_name, machine_id, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.post("/apps/#{app_name}/machines/#{machine_id}/start", %{})
|> handle_request(:start_machine)
end
@doc """
Stops a running machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to stop.
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the stopped machine data.
{:error, error()} on failure.
"""
@spec stop_machine(String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def stop_machine(app_name, machine_id, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.post("/apps/#{app_name}/machines/#{machine_id}/stop", %{})
|> handle_request(:stop_machine)
end
@doc """
Suspends a running machine.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to suspend.
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the suspended machine data.
{:error, error()} on failure.
"""
@spec suspend_machine(String.t(), String.t(), FlyMachineClient.options()) ::
FlyMachineClient.response()
def suspend_machine(app_name, machine_id, opts \\ []) do
client = FlyMachineClient.new(opts)
client
|> Tesla.post("/apps/#{app_name}/machines/#{machine_id}/suspend", %{})
|> handle_request(:suspend_machine)
end
@doc """
Waits for a machine to reach a specific state.
## Parameters
- app_name: The name of the app the machine belongs to.
- machine_id: The ID of the machine to wait for.
- instance_id: The ID of the instance to wait for.
- state: The desired state to wait for.
- timeout: The maximum time to wait (in seconds).
- opts: Optional. Additional options for the request.
## Returns
{:ok, machine} on success, where machine is the machine data after reaching the desired state.
{:error, error()} on failure or timeout.
"""
@spec wait_for_machine_state(
String.t(),
String.t(),
String.t(),
String.t(),
integer(),
FlyMachineClient.options()
) :: FlyMachineClient.response()
def wait_for_machine_state(
app_name,
machine_id,
instance_id,
state \\ "started",
timeout \\ 60,
opts \\ []
) do
client = FlyMachineClient.new(opts)
url = "/apps/#{app_name}/machines/#{machine_id}/wait"
client
|> Tesla.get(url, query: [instance_id: instance_id, state: state, timeout: timeout])
|> handle_request(:wait_for_machine_state)
end
end