Packages
A typed Elixir wrapper for the Docker CLI with struct-based commands and pipeline composition
Current section
Files
Jump to
Current section
Files
lib/docker/commands/exec.ex
defmodule Docker.Commands.Exec do
@moduledoc """
Implements the `Docker.Command` behaviour for `docker exec`.
## Examples
import Docker.Commands.Exec
"my-container"
|> new(["ls", "-la"])
|> Docker.exec_cmd()
"""
@behaviour Docker.Command
import Docker.Command, only: [add_flag: 3, add_opt: 3, add_repeat: 3]
@type t :: %__MODULE__{
container: String.t(),
command: [String.t()],
detach: boolean(),
interactive: boolean(),
tty: boolean(),
privileged: boolean(),
user: String.t() | nil,
workdir: String.t() | nil,
env: [{String.t(), String.t()}]
}
@enforce_keys [:container, :command]
defstruct [
:container,
:command,
:user,
:workdir,
detach: false,
interactive: false,
tty: false,
privileged: false,
env: []
]
def new(container, command) when is_list(command) do
%__MODULE__{container: container, command: command}
end
def new(container, command) when is_binary(command) do
%__MODULE__{container: container, command: [command]}
end
def detach(%__MODULE__{} = cmd), do: %{cmd | detach: true}
def interactive(%__MODULE__{} = cmd), do: %{cmd | interactive: true}
def tty(%__MODULE__{} = cmd), do: %{cmd | tty: true}
def privileged(%__MODULE__{} = cmd), do: %{cmd | privileged: true}
def user(%__MODULE__{} = cmd, u), do: %{cmd | user: u}
def workdir(%__MODULE__{} = cmd, w), do: %{cmd | workdir: w}
def env(%__MODULE__{} = cmd, key, value) do
%{cmd | env: cmd.env ++ [{to_string(key), to_string(value)}]}
end
@impl true
def args(%__MODULE__{} = cmd) do
["exec"]
|> add_flag(cmd.detach, "-d")
|> add_flag(cmd.interactive, "-i")
|> add_flag(cmd.tty, "-t")
|> add_flag(cmd.privileged, "--privileged")
|> add_opt(cmd.user, "--user")
|> add_opt(cmd.workdir, "--workdir")
|> add_repeat(cmd.env, fn {k, v} -> ["-e", "#{k}=#{v}"] end)
|> Kernel.++([cmd.container])
|> Kernel.++(cmd.command)
end
@impl true
def parse_output(stdout, 0), do: {:ok, stdout}
def parse_output(stdout, exit_code), do: {:error, {stdout, exit_code}}
end