Skip to content

Commit

Permalink
send filters to ryuk
Browse files Browse the repository at this point in the history
  • Loading branch information
jarlah committed Oct 12, 2023
1 parent bb84d89 commit 6ac79df
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 9 deletions.
60 changes: 51 additions & 9 deletions lib/reaper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,78 @@ defmodule TestcontainersElixir.Reaper do
@ryuk_port 8080

def start_link(connection) do
GenServer.start_link(__MODULE__, connection)
GenServer.start_link(__MODULE__, connection, name: __MODULE__)
end

def register(filter) do
GenServer.call(__MODULE__, {:register, filter})
end

@impl true
def init(connection) do
{:ok, _} =
connection
|> DockerEngineAPI.Api.Image.image_create(fromImage: @ryuk_image)

{:ok, container} =
{:ok, %DockerEngineAPI.Model.ContainerCreateResponse{Id: container_id} = container} =
connection
|> DockerEngineAPI.Api.Container.container_create(
%DockerEngineAPI.Model.ContainerCreateRequest{
Image: @ryuk_image,
ExposedPorts: %{"#{@ryuk_port}" => %{}},
HostConfig: %{
PortBindings: %{"8080" => [%{"HostPort" => ""}]},
PortBindings: %{"#{@ryuk_port}" => [%{"HostPort" => ""}]},
Privileged: true,
Binds: ["/var/run/docker.sock:/var/run/docker.sock:rw"]
},
Env: ["RYUK_PORT=8080"]
}
)

{:ok, container} =
{:ok, _} =
connection
|> DockerEngineAPI.Api.Container.container_start(container_id)

{:ok, socket} =
connection
|> DockerEngineAPI.Api.Container.container_start(container."Id")
|> connect_to_first_tcp_port(container, @ryuk_port)

{:ok, {container, socket}}
end

@impl true
def handle_call({:register, filter}, _from, {_connection, socket} = state) do
{:reply, do_register(socket, filter), state}
end

defp do_register(socket, {filter_key, filter_value}) do
:gen_tcp.send(socket, (docker_filter(filter_key, filter_value) <> "\n") |> IO.inspect())
wait_for_ack(socket)
:ok
end

defp connect_to_first_tcp_port(
connection,
%DockerEngineAPI.Model.ContainerCreateResponse{Id: container_id},
port
) do
port_str = "#{port}/tcp"

# TODO establish socket connection
# TODO send first message
# TODO return {:ok, {container, socket}} for ex
{:ok, container}
{:ok,
%DockerEngineAPI.Model.ContainerInspectResponse{
NetworkSettings: %{Ports: %{^port_str => [%{"HostPort" => host_port}]}}
}} = connection |> DockerEngineAPI.Api.Container.container_inspect(container_id)

:gen_tcp.connect(~c"localhost", String.to_integer(host_port), [
:binary,
active: false,
packet: :line
])
end

defp docker_filter(key, value), do: "#{url_encode(key)}=#{url_encode(value)}"

defp url_encode(string), do: :uri_string.quote(string)

defp wait_for_ack(socket), do: {:ok, "ACK\n"} = :gen_tcp.recv(socket, 0, 1_000)
end
1 change: 1 addition & 0 deletions lib/testcontainers_elixir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule TestcontainersElixir do
DockerEngineAPI.Connection.new(base_url: "http+unix://%2Fvar%2Frun%2Fdocker.sock/v1.43")

{:ok, _pid} = connection |> TestcontainersElixir.Reaper.start_link()
:ok = TestcontainersElixir.Reaper.register({"id", "some_container_id?"})
connection |> DockerEngineAPI.Api.Image.image_list()
end
end

0 comments on commit 6ac79df

Please sign in to comment.