Skip to content

Commit

Permalink
feat(#694): Add Ryuk container privileged custom configuration (#709)
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn authored Dec 12, 2022
1 parent 6556fe0 commit 8db93b2
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 30 deletions.
27 changes: 14 additions & 13 deletions docs/custom_configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

Testcontainers supports various configurations to set up your test environment. It automatically discovers the Docker environment and applies the configuration. You can set or override the default values either with the Testcontainers [properties file][properties-file-format] (`~/testcontainers.properties`) or with environment variables. If you prefer to configure your test environment at runtime, you can set or override the configuration through the `TestcontainersSettings` class. The following configurations are available:

| Properties File | Environment Variable | Description | Default |
|--------------------------|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------|-----------------------------|
| `docker.config` | `DOCKER_CONFIG` | The directory path that contains the Docker configuration (`config.json`) file. | `~/.docker/` |
| `docker.host` | `DOCKER_HOST` | The Docker daemon socket to connect to. | - |
| `docker.auth.config` | `DOCKER_AUTH_CONFIG` | The Docker configuration file content (GitLab: [Use statically-defined credentials][use-statically-defined-credentials]). | - |
| `docker.cert.path` | `DOCKER_CERT_PATH` | The directory path that contains the client certificate (`{ca,cert,key}.pem`) files. | `~/.docker/` |
| `docker.tls` | `DOCKER_TLS` | Enables TLS. | `false` |
| `docker.tls.verify` | `DOCKER_TLS_VERIFY` | Enables TLS verify. | `false` |
| `host.override` | `TESTCONTAINERS_HOST_OVERRIDE` | The host that exposes Docker's ports. | - |
| `docker.socket.override` | `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE` | The file path to the Docker daemon socket that is used by Ryuk (resource reaper). | `/var/run/docker.sock` |
| `ryuk.disabled` | `TESTCONTAINERS_RYUK_DISABLED` | Disables Ryuk (resource reaper). | `false` |
| `ryuk.container.image` | `TESTCONTAINERS_RYUK_CONTAINER_IMAGE` | The Ryuk (resource reaper) Docker image. | `testcontainers/ryuk:0.3.4` |
| `hub.image.name.prefix` | `TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX` | The name to use for substituting the Docker Hub registry part of the image name. | - |
| Properties File | Environment Variable | Description | Default |
|-----------------------------|--------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|-----------------------------|
| `docker.config` | `DOCKER_CONFIG` | The directory path that contains the Docker configuration (`config.json`) file. | `~/.docker/` |
| `docker.host` | `DOCKER_HOST` | The Docker daemon socket to connect to. | - |
| `docker.auth.config` | `DOCKER_AUTH_CONFIG` | The Docker configuration file content (GitLab: [Use statically-defined credentials][use-statically-defined-credentials]). | - |
| `docker.cert.path` | `DOCKER_CERT_PATH` | The directory path that contains the client certificate (`{ca,cert,key}.pem`) files. | `~/.docker/` |
| `docker.tls` | `DOCKER_TLS` | Enables TLS. | `false` |
| `docker.tls.verify` | `DOCKER_TLS_VERIFY` | Enables TLS verify. | `false` |
| `host.override` | `TESTCONTAINERS_HOST_OVERRIDE` | The host that exposes Docker's ports. | - |
| `docker.socket.override` | `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE` | The file path to the Docker daemon socket that is used by Ryuk (resource reaper). | `/var/run/docker.sock` |
| `ryuk.disabled` | `TESTCONTAINERS_RYUK_DISABLED` | Disables Ryuk (resource reaper). | `false` |
| `ryuk.container.privileged` | `TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED` | Runs Ryuk (resource reaper) in privileged mode. | `false` |
| `ryuk.container.image` | `TESTCONTAINERS_RYUK_CONTAINER_IMAGE` | The Ryuk (resource reaper) Docker image. | `testcontainers/ryuk:0.3.4` |
| `hub.image.name.prefix` | `TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX` | The name to use for substituting the Docker Hub registry part of the image name. | - |

## Enable logging

Expand Down
43 changes: 30 additions & 13 deletions src/Testcontainers/Configurations/CustomConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected CustomConfiguration(IReadOnlyDictionary<string, string> properties)

protected string GetDockerConfig(string propertyName)
{
return this.GetPropertyValue(propertyName);
return this.GetPropertyValue<string>(propertyName);
}

protected Uri GetDockerHost(string propertyName)
Expand All @@ -26,12 +26,12 @@ protected Uri GetDockerHost(string propertyName)

protected string GetDockerHostOverride(string propertyName)
{
return this.GetPropertyValue(propertyName);
return this.GetPropertyValue<string>(propertyName);
}

protected string GetDockerSocketOverride(string propertyName)
{
return this.GetPropertyValue(propertyName);
return this.GetPropertyValue<string>(propertyName);
}

protected JsonDocument GetDockerAuthConfig(string propertyName)
Expand All @@ -55,24 +55,27 @@ protected JsonDocument GetDockerAuthConfig(string propertyName)

protected string GetDockerCertPath(string propertyName)
{
return this.GetPropertyValue(propertyName);
return this.GetPropertyValue<string>(propertyName);
}

protected bool GetDockerTls(string propertyName)
{
_ = this.properties.TryGetValue(propertyName, out var propertyValue);
return "1".Equals(propertyValue, StringComparison.Ordinal) || (bool.TryParse(propertyValue, out var tlsEnabled) && tlsEnabled);
return this.GetPropertyValue<bool>(propertyName);
}

protected bool GetDockerTlsVerify(string propertyName)
{
_ = this.properties.TryGetValue(propertyName, out var propertyValue);
return "1".Equals(propertyValue, StringComparison.Ordinal) || (bool.TryParse(propertyValue, out var tlsVerifyEnabled) && tlsVerifyEnabled);
return this.GetPropertyValue<bool>(propertyName);
}

protected bool GetRyukDisabled(string propertyName)
{
return this.properties.TryGetValue(propertyName, out var propertyValue) && bool.TryParse(propertyValue, out var ryukDisabled) && ryukDisabled;
return this.GetPropertyValue<bool>(propertyName);
}

protected bool GetRyukContainerPrivileged(string propertyName)
{
return this.GetPropertyValue<bool>(propertyName);
}

protected IDockerImage GetRyukContainerImage(string propertyName)
Expand All @@ -96,13 +99,27 @@ protected IDockerImage GetRyukContainerImage(string propertyName)

protected string GetHubImageNamePrefix(string propertyName)
{
return this.GetPropertyValue(propertyName);
return this.GetPropertyValue<string>(propertyName);
}

private string GetPropertyValue(string propertyName)
private T GetPropertyValue<T>(string propertyName)
{
_ = this.properties.TryGetValue(propertyName, out var propertyValue);
return propertyValue;
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Boolean:
{
return (T)(object)(this.properties.TryGetValue(propertyName, out var propertyValue) && ("1".Equals(propertyValue, StringComparison.Ordinal) || (bool.TryParse(propertyValue, out var result) && result)));
}

case TypeCode.String:
{
_ = this.properties.TryGetValue(propertyName, out var propertyValue);
return (T)(object)propertyValue;
}

default:
throw new ArgumentOutOfRangeException(typeof(T).Name);
}
}
}
}
9 changes: 9 additions & 0 deletions src/Testcontainers/Configurations/EnvironmentConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ internal sealed class EnvironmentConfiguration : CustomConfiguration, ICustomCon

private const string RyukDisabled = "TESTCONTAINERS_RYUK_DISABLED";

private const string RyukContainerPrivileged = "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED";

private const string RyukContainerImage = "TESTCONTAINERS_RYUK_CONTAINER_IMAGE";

private const string HubImageNamePrefix = "TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX";
Expand All @@ -51,6 +53,7 @@ public EnvironmentConfiguration()
DockerHostOverride,
DockerSocketOverride,
RyukDisabled,
RyukContainerPrivileged,
RyukContainerImage,
HubImageNamePrefix,
}
Expand Down Expand Up @@ -118,6 +121,12 @@ public bool GetRyukDisabled()
return this.GetRyukDisabled(RyukDisabled);
}

/// <inheritdoc />
public bool GetRyukContainerPrivileged()
{
return this.GetRyukContainerPrivileged(RyukContainerPrivileged);
}

/// <inheritdoc />
public IDockerImage GetRyukContainerImage()
{
Expand Down
7 changes: 7 additions & 0 deletions src/Testcontainers/Configurations/ICustomConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ internal interface ICustomConfiguration
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
bool GetRyukDisabled();

/// <summary>
/// Gets the Ryuk container privileged custom configuration.
/// </summary>
/// <returns>The Ryuk container privileged custom configuration.</returns>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
bool GetRyukContainerPrivileged();

/// <summary>
/// Gets the Ryuk container image custom configuration.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ public bool GetRyukDisabled()
return this.GetRyukDisabled(propertyName);
}

/// <inheritdoc />
public bool GetRyukContainerPrivileged()
{
const string propertyName = "ryuk.container.privileged";
return this.GetRyukContainerPrivileged(propertyName);
}

/// <inheritdoc />
public IDockerImage GetRyukContainerImage()
{
Expand Down
4 changes: 0 additions & 4 deletions src/Testcontainers/Containers/ResourceReaper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,6 @@ public async ValueTask DisposeAsync()
await this.maintainConnectionTask
.ConfigureAwait(false);
}
catch (Exception)
{
// Ignore
}
finally
{
this.maintainConnectionCts.Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ static EnvironmentConfigurationTest()
EnvironmentVariables.Add("TESTCONTAINERS_HOST_OVERRIDE");
EnvironmentVariables.Add("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE");
EnvironmentVariables.Add("TESTCONTAINERS_RYUK_DISABLED");
EnvironmentVariables.Add("TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED");
EnvironmentVariables.Add("TESTCONTAINERS_RYUK_CONTAINER_IMAGE");
EnvironmentVariables.Add("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX");
}
Expand Down Expand Up @@ -142,6 +143,18 @@ public void GetRyukDisabledCustomConfiguration(string propertyName, string prope
Assert.Equal(expected, customConfiguration.GetRyukDisabled());
}

[Theory]
[InlineData("", "", false)]
[InlineData("TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED", "", false)]
[InlineData("TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED", "false", false)]
[InlineData("TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED", "true", true)]
public void GetRyukContainerPrivilegedCustomConfiguration(string propertyName, string propertyValue, bool expected)
{
SetEnvironmentVariable(propertyName, propertyValue);
ICustomConfiguration customConfiguration = new EnvironmentConfiguration();
Assert.Equal(expected, customConfiguration.GetRyukContainerPrivileged());
}

[Theory]
[InlineData("", "", null)]
[InlineData("TESTCONTAINERS_RYUK_CONTAINER_IMAGE", "", null)]
Expand Down Expand Up @@ -288,6 +301,17 @@ public void GetRyukDisabledCustomConfiguration(string configuration, bool expect
Assert.Equal(expected, customConfiguration.GetRyukDisabled());
}

[Theory]
[InlineData("", false)]
[InlineData("ryuk.container.privileged=", false)]
[InlineData("ryuk.container.privileged=false", false)]
[InlineData("ryuk.container.privileged=true", true)]
public void GetRyukContainerPrivilegedCustomConfiguration(string configuration, bool expected)
{
ICustomConfiguration customConfiguration = new PropertiesFileConfiguration(new[] { configuration });
Assert.Equal(expected, customConfiguration.GetRyukContainerPrivileged());
}

[Theory]
[InlineData("", null)]
[InlineData("ryuk.container.image=", null)]
Expand Down

0 comments on commit 8db93b2

Please sign in to comment.