Packages

Elixir client for the Docker Remote API.

Current section

Files

Jump to
docker lib config.ex
Raw

lib/config.ex

defmodule Docker.Config do
defstruct name: nil,
image: nil,
command: "",
entrypoint: "",
ports: %{}, # %{name: "container_port:host_port"}
volumes: %{}, # %{host_mount: container_mount}
remove: false,
environment: %{},
user: "",
working_dir: "",
hostname: nil,
net: "bridge",
generic_hostname: false
@doc """
Given a %Docker.Config{} struct, formats and returns a dictionary of the appropiate options
for creating a container.
"""
def create_container(conf = %Docker.Config{generic_hostname: false}) do
{:ok, os_hostname} = :inet.gethostname
hostname = conf.hostname || "#{conf.name}-#{os_hostname}"
conf
|> Map.put(:hostname, hostname)
|> Map.delete(:generic_hostname)
|> create_container
end
def create_container(conf = %Docker.Config{}) do
%{"Hostname" => conf.hostname,
"User" => conf.user,
"Entrypoint" => conf.entrypoint,
"AttachStdin" => conf.remove,
"Env" => format_environment(conf.environment),
"Cmd" => conf.command |> OptionParser.split,
"Image" => conf.image,
"Volumes" => map_empty_dict(conf.volumes, 1),
"WorkingDir" => conf.working_dir,
"ExposedPorts" => format_ports(conf.ports),
"NetworkDisabled" => conf.net == "none",
"HostConfig" => %{
"NetworkMode" => conf.net,
},
}
end
@doc """
Given a %Docker.Config{} struct, formats and returns a dictionary of the appropriate
options for starting a container.
"""
def start_container(conf = %Docker.Config{ports: %{}}) do
port_map = conf.ports
|> Dict.values
|> Enum.map(&port_to_tuple/1)
|> Enum.map(&({elem(&1, 0), [%{"HostPort" => elem(&1, 1)}]}))
|> Enum.into(%{})
%{"Binds" => format_volumes(conf.volumes),
"PortBindings" => port_map,
"NetworkMode" => conf.net,
}
end
def start_container(conf = %Docker.Config{}) do
%{"Binds" => format_volumes(conf.volumes)}
end
def format_environment(nil), do: []
def format_environment(env = %{}) do
Enum.map(env, &(elem(&1, 0) <> "=" <> elem(&1, 1)))
end
def format_ports(nil), do: %{}
def format_ports(ports = %{}) do
ports
|> Dict.values
|> Enum.map(&port_to_tuple/1)
|> map_empty_dict(0)
end
def format_volumes(nil), do: nil
def format_volumes(volumes = %{}) do
volumes |> Enum.map(&(to_string(elem(&1, 0)) <> ":" <> elem(&1, 1)))
end
@doc """
Takes a port string, either a single port or : deliminated pair,
and turns it into a two-element tuple.
"""
def port_to_tuple(port) when is_binary(port) do
port |> String.split(":") |> port_to_tuple
end
def port_to_tuple([container_port, host_port]) do
{port_protocol(container_port), host_port}
end
def port_to_tuple([port]) do
host_port = port |> String.split("/") |> List.first
{port_protocol(port), host_port}
end
defp port_protocol([port, protocol]), do: port <> "/" <> protocol
defp port_protocol([port]), do: port <> "/tcp"
defp port_protocol(port), do: String.split(port, "/") |> port_protocol
defp map_empty_dict(nil, _), do: %{}
defp map_empty_dict(dict, element) do
Enum.map(dict, &({elem(&1, element), %{}})) |> Enum.into(%{})
end
end