Skip to content

Commit

Permalink
Fix to allow for force pull in UseImage fluent API.
Browse files Browse the repository at this point in the history
This allows a force pull from either private or public repo and solves Issue #84.
  • Loading branch information
Mario Toffia committed May 3, 2019
1 parent 831dd51 commit 8946d91
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 44 deletions.
2 changes: 1 addition & 1 deletion Ductus.FluentDocker.Tests/CommandTests/ImageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void ImageConfigurationShallBeRetrievable()
[TestMethod]
public void ImageIsExposedOnARunningContainer()
{
using (var container = DockerHost.Create("postgres:9.6-alpine",
using (var container = DockerHost.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Threading.Tasks;
using Ductus.FluentDocker.Builders;
using Ductus.FluentDocker.Commands;
using Ductus.FluentDocker.Extensions;
using Ductus.FluentDocker.Model.Builders;
using Ductus.FluentDocker.Model.Common;
Expand Down Expand Up @@ -440,29 +441,22 @@ public void ReuseOfExistingContainerShallWork()
{
}
}

[TestMethod]
public void StaticIpv4InCustomNetworkShallWork()
public void PullContainerBeforeRunningShallWork()
{
using (var nw = Fd.UseNetwork("unit-test-nw")
.UseSubnet("10.18.0.0/16").Build())
using (
var container =
Fd.UseContainer()
.UseImage("postgres:latest", force: true)
.ExposePort(5432)
.WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
.WaitForProcess("postgres", 30000 /*30s*/)
.Build()
.Start())
{
using (
var container =
Fd.UseContainer()
.WithName("mycontainer")
.UseImage("postgres:9.6-alpine")
.WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
.ExposePort(5432)
.UseNetwork(nw)
.UseIpV4("10.18.0.22")
.WaitForPort("5432/tcp", 30000 /*30s*/)
.Build()
.Start())
{
var ip = container.GetConfiguration().NetworkSettings.Networks["unit-test-nw"].IPAddress;
Assert.AreEqual("10.18.0.22", ip);
}
var config = container.GetConfiguration(true);
AreEqual(ServiceRunningState.Running, config.State.ToServiceState());
}
}
}
Expand Down
85 changes: 85 additions & 0 deletions Ductus.FluentDocker.Tests/FluentApiTests/FluentNetworkTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Threading.Tasks;
using Ductus.FluentDocker.Extensions;
using Ductus.FluentDocker.Services.Extensions;
using Ductus.FluentDocker.Tests.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Ductus.FluentDocker.Tests.FluentApiTests
{
[TestClass]
public class FluentNetworkTests
{
[ClassInitialize]
public static void Initialize(TestContext ctx)
{
Utilities.LinuxMode();
}

[TestMethod]
public void StaticIpv4InCustomNetworkShallWork()
{
using (var nw = Fd.UseNetwork("unit-test-nw")
.UseSubnet("10.18.0.0/16").Build())
{
using (
var container =
Fd.UseContainer()
.WithName("mycontainer")
.UseImage("postgres:9.6-alpine")
.WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
.ExposePort(5432)
.UseNetwork(nw)
.UseIpV4("10.18.0.22")
.WaitForPort("5432/tcp", 30000 /*30s*/)
.Build()
.Start())
{
var ip = container.GetConfiguration().NetworkSettings.Networks["unit-test-nw"].IPAddress;
Assert.AreEqual("10.18.0.22", ip);
}
}
}

[TestMethod]
public void InternalNetworkExposedToHostShallWork()
{
using (var nw = Fd.UseNetwork("unit-test-nw")
.UseDriver("bridge")
.IsInternal()
.Build())
{
// Ping outside shall not work
using (
var container =
Fd.UseContainer()
.WithName("internal-container")
.UseImage("alpine")
.UseNetwork(nw)
.Command("ping", "1.1.1.1", "-c 1", "-w 5", "-W 5")
.Build()
.Start())
{
var log = container.Logs().ReadToEnd(30_000);
var c = container.GetConfiguration(true);
var ec = c.State.ExitCode;
Assert.AreEqual(1, ec);
}

// Gain access to the container from host shall work
using (var container =
Fd.UseContainer()
.UseImage("nginx:1.13.6-alpine")
.ExposePort(80)
.UseNetwork(nw)
.WaitForPort("80/tcp", 30000 /*30s*/)
.Build()
.Start())
{
var response = $"http://{container.ToHostExposedEndpoint("80/tcp")}".Wget().Result;
Console.WriteLine(response);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static void TearDown()
[TestMethod]
public void CreateContainerMakesServiceStopped()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"}
Expand Down Expand Up @@ -91,7 +91,7 @@ public void Issue_69_Container_name_lost_first_char()
[TestMethod]
public void CreateAndStartContainerWithEnvironment()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"}
Expand All @@ -108,7 +108,7 @@ public void CreateAndStartContainerWithEnvironment()
[TestMethod]
public void DeleteVolumesOnContainerDisposeShallWork()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"}
Expand All @@ -129,7 +129,7 @@ public void DeleteNamedVolumesOnContainerDisposeShallWork()
{
_host.Host.VolumeCreate("unit-test-volume");

using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"},
Expand Down Expand Up @@ -168,7 +168,7 @@ public void ListVolumesShallWork()
[TestMethod]
public void CreateAndStartContainerWithOneExposedPortVerified()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
PortMappings = new[] {"40001:5432"},
Expand All @@ -190,7 +190,7 @@ public void CreateAndStartContainerWithOneExposedPortVerified()
[TestMethod]
public void ProcessesInContainerAndManuallyVerifyPostgresIsRunning()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
PortMappings = new[] {"40001:5432"},
Expand All @@ -213,7 +213,7 @@ public void ProcessesInContainerAndManuallyVerifyPostgresIsRunning()
[TestMethod]
public void ExportRunningContainerToTarFileShallSucceed()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
PortMappings = new[] {"40001:5432"},
Expand Down Expand Up @@ -246,7 +246,7 @@ public void ExportRunningContainerToTarFileShallSucceed()
[TestMethod]
public void ExportRunningContainerExploadedShallSucceed()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
PortMappings = new[] {"40001:5432"},
Expand Down Expand Up @@ -285,7 +285,7 @@ public async Task UseHostVolumeInsideContainerWhenMountedShallSucceed()
var fullPath = (TemplateString) @"${TEMP}\fluentdockertest\${RND}";
Directory.CreateDirectory(fullPath);

using (var container = _host.Create("nginx:1.13.6-alpine",
using (var container = _host.Create("nginx:1.13.6-alpine", false,
new ContainerCreateParams
{
PortMappings = new[] {"80"},
Expand All @@ -308,7 +308,7 @@ public async Task UseHostVolumeInsideContainerWhenMountedShallSucceed()
[TestMethod]
public void CopyFromRunningContainerShallWork()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"}
Expand Down Expand Up @@ -337,7 +337,7 @@ public void CopyFromRunningContainerShallWork()
[TestMethod]
public void CopyToRunningContainerShallWork()
{
using (var container = _host.Create("postgres:9.6-alpine",
using (var container = _host.Create("postgres:9.6-alpine", false,
new ContainerCreateParams
{
Environment = new[] {"POSTGRES_PASSWORD=mysecretpassword"}
Expand Down
5 changes: 3 additions & 2 deletions Ductus.FluentDocker/Builders/ContainerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public override IContainerService Build()

if (string.Empty != firstNw) _config.CreateParams.Network = firstNw;

var container = host.Value.Create(_config.Image, _config.CreateParams, _config.StopOnDispose,
var container = host.Value.Create(_config.Image, _config.ImageFocrePull, _config.CreateParams, _config.StopOnDispose,
_config.DeleteOnDispose,
_config.DeleteVolumeOnDispose,
_config.DeleteNamedVolumeOnDispose,
Expand Down Expand Up @@ -100,9 +100,10 @@ public ContainerBuilder RemoveVolumesOnDispose(bool includeNamedVolues = false)
return this;
}

public ContainerBuilder UseImage(string image)
public ContainerBuilder UseImage(string image, bool force = false)
{
_config.Image = image;
_config.ImageFocrePull = force;
return this;
}

Expand Down
22 changes: 17 additions & 5 deletions Ductus.FluentDocker/Builders/NetworkBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public sealed class NetworkBuilder : BaseBuilder<INetworkService>
private readonly NetworkCreateParams _config = new NetworkCreateParams();
private string _name;
private bool _removeOnDispose = true;
private bool _reuseIfExist = false;
private bool _reuseIfExist;

public NetworkBuilder(IBuilder parent, string name = null) : base(parent)
{
Expand All @@ -28,10 +28,7 @@ public override INetworkService Build()
if (_reuseIfExist)
{
var network = host.Value.GetNetworks().FirstOrDefault(x => x.Name == _name);
if (null != network)
{
return network;
}
if (null != network) return network;
}

return host.Value.CreateNetwork(_name, _config, _removeOnDispose);
Expand Down Expand Up @@ -69,6 +66,7 @@ public NetworkBuilder KeepOnDispse()
_removeOnDispose = false;
return this;
}

public NetworkBuilder KeepOnDispose()
{
_removeOnDispose = false;
Expand Down Expand Up @@ -110,6 +108,20 @@ public NetworkBuilder IsInternal()
return this;
}

/// <summary>
/// Enables manual container attachment to the network.
/// </summary>
/// <returns>Itself for fluent access.</returns>
/// <remarks>
/// By default manual attachment of containers is set to false.
/// This is vital if e.g. overlay network with internal is specified.
/// </remarks>
public NetworkBuilder IsAttachAble()
{
_config.Attachable = true;
return this;
}

public NetworkBuilder UseIpRange(params string[] iprange)
{
_config.IpRange = iprange;
Expand Down
8 changes: 7 additions & 1 deletion Ductus.FluentDocker/Executors/ConsoleStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,18 @@ public T Read()

public T TryRead(int millisTimeout)
{
T result;
if (IsFinished)
{
if (_values.TryTake(out result, 10, _token))
{
return result;
}

return null;
}

T result;

if (_values.TryTake(out result, millisTimeout, _token))
{
return result;
Expand Down
6 changes: 4 additions & 2 deletions Ductus.FluentDocker/Executors/Mappers/StringMapper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace Ductus.FluentDocker.Executors.Mappers
using System;

namespace Ductus.FluentDocker.Executors.Mappers
{
public sealed class StringMapper : IStreamMapper<string>
{
{
public string OnData(string data, bool isStdErr)
{
return data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public ContainerBuilderConfig()
public bool VerifyExistence { get; set; }
public ContainerCreateParams CreateParams { get; }
public string Image { get; set; }
public bool ImageFocrePull { get; set; }
public bool IsWindowsImage { get; set; }
public bool StopOnDispose { get; set; } = true;
public bool DeleteOnDispose { get; set; } = true;
Expand Down
9 changes: 9 additions & 0 deletions Ductus.FluentDocker/Model/Containers/NetworkCreateParams.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ namespace Ductus.FluentDocker.Model.Containers
{
public sealed class NetworkCreateParams
{
/// <summary>
/// Enables manual container attachment (disabled by default)
/// </summary>
/// <remarks>
/// --attachable
/// </remarks>
public bool Attachable { get; set; }

/// <summary>
/// Auxiliary ipv4 or ipv6 addresses used by Network driver
/// </summary>
Expand Down Expand Up @@ -97,6 +105,7 @@ public sealed class NetworkCreateParams
public override string ToString()
{
return new StringBuilder()
.OptionIfExists("--attachable", Attachable)
.OptionIfExists("--aux-address=", AuxAddress)
.OptionIfExists("--driver=", Driver)
.OptionIfExists("--opt=", DriverOptions)
Expand Down
3 changes: 2 additions & 1 deletion Ductus.FluentDocker/Services/IHostService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public interface IHostService : IService
/// Creates a new container (not started).
/// </summary>
/// <param name="image">The image to base the container from.</param>
/// <param name="forcePull">If the image shall be forced downloaded or not. Default is false.</param>
/// <param name="prms">Optionally paramters to configure the container.</param>
/// <param name="stopOnDispose">If the docker container shall be stopped when service is disposed.</param>
/// <param name="deleteOnDispose">If the docker container shall be deleted when the service is disposed.</param>
Expand All @@ -58,7 +59,7 @@ public interface IHostService : IService
/// <param name="args">Optionally a set of parameters to go with the <see cref="command" /> when started.</param>
/// <returns>A service reflecting the newly created container.</returns>
/// <exception cref="FluentDockerException">If error occurs.</exception>
IContainerService Create(string image, ContainerCreateParams prms = null,
IContainerService Create(string image, bool forcePull = false, ContainerCreateParams prms = null,
bool stopOnDispose = true, bool deleteOnDispose = true, bool deleteVolumeOnDispose = false,
bool deleteNamedVolumeOnDispose = false, string command = null,
string[] args = null);
Expand Down
Loading

0 comments on commit 8946d91

Please sign in to comment.