Skip to content

Commit

Permalink
fix for missing rootless support
Browse files Browse the repository at this point in the history
  • Loading branch information
jarlah committed Nov 10, 2024
1 parent 480355d commit 2ffbe33
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
18 changes: 13 additions & 5 deletions lib/connection/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ defmodule Testcontainers.Connection do
@timeout 300_000

def get_connection(options \\ []) do
docker_host_url = docker_base_url()
{docker_host_url, docker_host} = get_docker_host_url()

Logger.log("Using docker host url: #{docker_host_url}")

Expand All @@ -25,10 +25,18 @@ defmodule Testcontainers.Connection do
user_agent: Constants.user_agent()
)

{Connection.new(options), docker_host_url}
{Connection.new(options), docker_host_url, docker_host}
end

defp docker_base_url do
defp get_docker_host_url do
with {:ok, docker_host} <- get_docker_host() do
{DockerUrl.construct(docker_host), docker_host}
else {:error, error} ->
exit(error)
end
end

defp get_docker_host do
strategies = [
%DockerHostFromPropertiesStrategy{key: "tc.host"},
%DockerHostFromEnvStrategy{},
Expand All @@ -39,10 +47,10 @@ defmodule Testcontainers.Connection do

case DockerHostStrategyEvaluator.run_strategies(strategies, []) do
{:ok, docker_host} ->
DockerUrl.construct(docker_host)
{:ok, docker_host}

:error ->
exit("Failed to find docker host")
{:error, "Failed to find docker host"}
end
end
end
29 changes: 22 additions & 7 deletions lib/testcontainers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Testcontainers do
This is a GenServer that needs to be started before anything can happen.
"""

alias Testcontainers.Constants
alias Testcontainers.WaitStrategy
alias Testcontainers.Logger
alias Testcontainers.Docker.Api
Expand All @@ -31,17 +32,31 @@ defmodule Testcontainers do
end

defp setup(options) do
{conn, docker_host_url} = Connection.get_connection(options)
{conn, docker_host_url, docker_host} = Connection.get_connection(options)

session_id =
:crypto.hash(:sha, "#{inspect(self())}#{DateTime.utc_now() |> DateTime.to_string()}")
|> Base.encode16()

ryuk_config =
Container.new("testcontainers/ryuk:0.9.0")
Container.new("testcontainers/ryuk:#{Constants.ryuk_version}")
|> Container.with_exposed_port(8080)
|> Container.with_environment("RYUK_PORT", "8080")
|> Container.with_bind_mount("/var/run/docker.sock", "/var/run/docker.sock", "rw")
|> then(fn config ->
# docker_host can be anything from an url like https://localhost:1234 to unix:///etc/....
# if its a unix socket, strip the prefix and use the unix socket as the bind mount for Ryuks unix socket
# this enables ryuk to communicate with docker environment it runs in, to stop and remove containers
if String.starts_with?(docker_host, "unix://") do
Container.with_bind_mount(
config,
String.replace_prefix(docker_host, "unix://", ""),
"/var/run/docker.sock",
"rw"
)
else
config
end
end)
|> Container.with_auto_remove(true)

with {:ok, _} <- Api.pull_image(ryuk_config.image, conn),
Expand All @@ -50,15 +65,15 @@ defmodule Testcontainers do
{:ok, container} <- Api.get_container(ryuk_container_id, conn),
{:ok, socket} <- create_ryuk_socket(container),
:ok <- register_ryuk_filter(session_id, socket),
{:ok, docker_host} <- get_docker_host(docker_host_url, conn),
{:ok, docker_hostname} <- get_docker_hostname(docker_host_url, conn),
{:ok, properties} <- PropertiesParser.read_property_file() do
Logger.log("Testcontainers initialized")

{:ok,
%{
socket: socket,
conn: conn,
docker_host: docker_host,
docker_hostname: docker_hostname,
session_id: session_id,
properties: properties
}}
Expand Down Expand Up @@ -146,12 +161,12 @@ defmodule Testcontainers do

@impl true
def handle_call(:get_host, _from, state) do
{:reply, state.docker_host, state}
{:reply, state.docker_hostname, state}
end

# private functions

defp get_docker_host(docker_host_url, conn) do
defp get_docker_hostname(docker_host_url, conn) do
case URI.parse(docker_host_url) do
uri when uri.scheme == "http" or uri.scheme == "https" ->
{:ok, uri.host}
Expand Down
1 change: 1 addition & 0 deletions lib/util/constants.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule Testcontainers.Constants do

def library_name, do: :testcontainers
def library_version, do: "1.11.2"
def ryuk_version, do: "0.11.0"
def container_label, do: "org.testcontainers"
def container_lang_label, do: "org.testcontainers.lang"
def container_reuse_hash_label, do: "org.testcontainers.reuse-hash"
Expand Down

0 comments on commit 2ffbe33

Please sign in to comment.