defmodule Compox.Docker.API.Containers do @moduledoc false require Logger @base_uri "/containers" @doc """ Get the container id of the given container name. """ def get_id(container_name) when is_binary(container_name) do filters = %{name: [container_name]} "#{@base_uri}/json" |> Compox.Docker.API.Client.add_query_params(filters) |> Compox.Docker.API.Client.do_get() |> decode_list_response |> case do {:ok, containers} -> Enum.reduce_while(containers, "", fn %{"Id" => container_id} = container_found, _acc -> if match_partial_name(container_found, container_name) do {:halt, container_id} else {:cont, ""} end _container, _acc -> {:cont, ""} end) _ -> "" end end defp decode_list_response(%{ body: body, status: status }) do case Jason.decode(body) do {:ok, dict} -> case status do 200 -> {:ok, dict} 400 -> {:error, "Bad parameter"} 500 -> {:error, "Server error"} code -> {:error, "Unknown code: #{code}"} end {:error, message} -> {:error, message} end end defp decode_list_response(o) do Logger.warn(inspect o) end @doc """ Inspect a container by ID. """ def do_inspect(container_id) do "#{@base_uri}/#{container_id}/json" |> Compox.Docker.API.Client.do_get() |> decode_inspect_response end defp decode_inspect_response(%{ body: body, status: status }) do case Jason.decode(body) do {:ok, dict} -> case status do 200 -> {:ok, dict} 404 -> {:error, "No such container"} 500 -> Logger.error(Kernel.inspect(body)) {:error, "Server error"} code -> {:error, "Unknown code: #{code}"} end {:error, message} -> {:error, message} end end @doc """ Check if a container is running. """ @spec running?(String.t()) :: boolean def running?(container_id) when is_binary(container_id) do container_id |> do_inspect() |> case do %{"State" => %{ "Running" => true }} -> true _ -> false end end defp match_partial_name(container, name) do container |> Map.get("Names", []) |> Enum.any?(fn container_name -> container_name == name || container_name == "/#{name}" end) end end