Skip to content

Commit

Permalink
Merge pull request #217 from mariotoffia/feature-compose-project-dir
Browse files Browse the repository at this point in the history
Feature compose project dir
  • Loading branch information
mariotoffia authored Sep 29, 2021
2 parents 07eaf15 + 54a8564 commit 23828e2
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 41 deletions.
17 changes: 13 additions & 4 deletions Ductus.FluentDocker.Tests/CommandTests/ComposeCommandTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Ductus.FluentDocker.Commands;
using Ductus.FluentDocker.Extensions;
using Ductus.FluentDocker.Model.Common;
using Ductus.FluentDocker.Services;
using Ductus.FluentDocker.Services.Extensions;
using Ductus.FluentDocker.Services.Impl;
using Ductus.FluentDocker.Tests.Compose;
Expand Down Expand Up @@ -33,7 +31,13 @@ public async Task

try
{
var result = DockerHost.Host.ComposeUp(composeFile: file, certificates: DockerHost.Certificates);
var result = DockerHost.Host
.ComposeUpCommand(new Commands.Compose.ComposeUpCommandArgs
{
ComposeFiles = new System.Collections.Generic.List<string>() { file },
Certificates = DockerHost.Certificates
});

Assert.IsTrue(result.Success);

var ids = DockerHost.Host.ComposePs(composeFile: file, certificates: DockerHost.Certificates);
Expand Down Expand Up @@ -83,8 +87,13 @@ public void Issue79_DockerComposeOnDockerMachineShallWork()
typeof(NsResolver).ResourceExtract(fullPath);

var hostService = new DockerHostService("wifi-test");

var composeResponse = hostService.Host
.ComposeUp(composeFile: file, certificates: hostService.Certificates);
.ComposeUpCommand(new Commands.Compose.ComposeUpCommandArgs
{
ComposeFiles = new System.Collections.Generic.List<string>() { file },
Certificates = hostService.Certificates
});
}
}
}
11 changes: 11 additions & 0 deletions Ductus.FluentDocker/Builders/CompositeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,17 @@ public CompositeBuilder FromFile(params string[] composeFile)
return this;
}

/// <summary>
/// Explicitly sets the project directory.
/// </summary>
/// <param name="projectDir">The project dir, if none set it to an empty string.</param>
/// <returns>Itself for fluent access.</returns>
public CompositeBuilder UseProjectDir(TemplateString projectDir)
{
_config.ProjectDirectory = projectDir;
return this;
}

public CompositeBuilder ForceRecreate()
{
_config.ForceRecreate = true;
Expand Down
86 changes: 65 additions & 21 deletions Ductus.FluentDocker/Commands/Compose.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Ductus.FluentDocker.Executors;
using Ductus.FluentDocker.Executors.Parsers;
using Ductus.FluentDocker.Extensions;
Expand Down Expand Up @@ -406,64 +407,107 @@ public static CommandResponse<IList<string>> ComposeDown(this DockerUri host, st
$"{args} down {options}", cwd.NeedCwd ? cwd.Cwd : null).ExecutionEnvironment(env).Execute();
}

[Obsolete("Use ComposeUpCommand(...)")]
public static CommandResponse<IList<string>> ComposeUp(this DockerUri host,
string altProjectName = null,
bool forceRecreate = false, bool noRecreate = false, bool dontBuild = false,
bool buildBeforeCreate = false, TimeSpan? timeout = null,
bool removeOphans = false,
bool removeOrphans = false,
bool useColor = false,
bool noStart = false,
string[] services = null /*all*/,
IDictionary<string, string> env = null,
ICertificatePaths certificates = null, params string[] composeFile)
{
if (forceRecreate && noRecreate)
return host.ComposeUpCommand(new ComposeUpCommandArgs
{
throw new InvalidOperationException($"{nameof(forceRecreate)} and {nameof(noRecreate)} are incompatible.");
AltProjectName = altProjectName,
ForceRecreate = forceRecreate,
NoRecreate = noRecreate,
DontBuild = dontBuild,
BuildBeforeCreate = buildBeforeCreate,
Timeout = timeout,
RemoveOrphans = removeOrphans,
UseColor = useColor,
NoStart = noStart,
Services = services,
Env = env,
Certificates = certificates,
ComposeFiles = composeFile
});
}

public struct ComposeUpCommandArgs
{
public string AltProjectName {get;set;}
public bool ForceRecreate {get;set;}
public bool NoRecreate {get;set;}
public bool DontBuild {get;set;}
public bool BuildBeforeCreate {get;set;}
public TimeSpan? Timeout {get;set;}
public bool RemoveOrphans {get;set;}
public bool UseColor {get;set;}
public bool NoStart {get;set;}
public IList<string> Services {get;set;}
public IDictionary<string, string> Env {get;set;}
public ICertificatePaths Certificates {get;set;}
public IList<string> ComposeFiles {get;set;}
public TemplateString ProjectDirectory {get;set;}
}

public static CommandResponse<IList<string>> ComposeUpCommand(this DockerUri host, ComposeUpCommandArgs ca)
{
if (ca.ForceRecreate && ca.NoRecreate)
{
throw new InvalidOperationException("ForceRecreate and NoRecreate are incompatible.");
}

var cwd = WorkingDirectory(composeFile);
var cwd = WorkingDirectory(ca.ComposeFiles.ToArray());

var args = $"{host.RenderBaseArgs(certificates)}";
var args = $"{host.RenderBaseArgs(ca.Certificates)}";

if (null != composeFile && 0 != composeFile.Length)
foreach (var cf in composeFile)
if (null != ca.ComposeFiles && 0 != ca.ComposeFiles.Count)
foreach (var cf in ca.ComposeFiles)
if (!string.IsNullOrEmpty(cf))
args += $" -f \"{cf}\"";

if (!string.IsNullOrEmpty(altProjectName))
args += $" -p {altProjectName}";
if (!string.IsNullOrEmpty(ca.AltProjectName))
args += $" -p {ca.AltProjectName}";

var options = noStart ? "--no-start" : "--detach";
var options = ca.NoStart ? "--no-start" : "--detach";

if (forceRecreate)
if (ca.ForceRecreate)
options += " --force-recreate";

if (noRecreate)
if (ca.NoRecreate)
options += " --no-recreate";

if (dontBuild)
if (ca.DontBuild)
options += " --no-build";

if (buildBeforeCreate)
if (ca.BuildBeforeCreate)
options += " --build";

if (!useColor)
if (!ca.UseColor)
options += " --no-color";

if (null != timeout)
options += $" -t {Math.Round(timeout.Value.TotalSeconds, 0)}";
if (null != ca.Timeout)
options += $" -t {Math.Round(ca.Timeout.Value.TotalSeconds, 0)}";

if (removeOphans)
if (ca.RemoveOrphans)
options += " --remove-orphans";

if (null != services && 0 != services.Length)
options += " " + string.Join(" ", services);
if (!string.IsNullOrEmpty(ca.ProjectDirectory)) {
options += $" --project-directory {ca.ProjectDirectory.Rendered}";
}

if (null != ca.Services && 0 != ca.Services.Count)
options += " " + string.Join(" ", ca.Services);

return
new ProcessExecutor<StringListResponseParser, IList<string>>(
"docker-compose".ResolveBinary(),
$"{args} up {options}", cwd.NeedCwd ? cwd.Cwd : null).ExecutionEnvironment(env).Execute();
$"{args} up {options}", cwd.NeedCwd ? cwd.Cwd : null).ExecutionEnvironment(ca.Env).Execute();
}

public static CommandResponse<IList<string>> ComposeRm(this DockerUri host, string altProjectName = null,
Expand Down
2 changes: 2 additions & 0 deletions Ductus.FluentDocker/Model/Compose/DockerComposeConfig.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Ductus.FluentDocker.Model.Images;
using Ductus.FluentDocker.Model.Common;

namespace Ductus.FluentDocker.Model.Compose
{
Expand All @@ -24,6 +25,7 @@ public class DockerComposeConfig
public bool StopOnDispose { get; set; } = true;
public bool KeepContainers { get; set; }
public IDictionary<string, string> EnvironmentNameValue { get; set; } = new Dictionary<string, string>();
public TemplateString ProjectDirectory {get;set;}

public IDictionary<string, ContainerSpecificConfig> ContainerConfiguration { get; } =
new Dictionary<string, ContainerSpecificConfig>();
Expand Down
53 changes: 37 additions & 16 deletions Ductus.FluentDocker/Services/Impl/DockerComposeCompositeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Ductus.FluentDocker.Extensions;
using Ductus.FluentDocker.Model.Compose;
using Ductus.FluentDocker.Model.Containers;
using static Ductus.FluentDocker.Commands.Compose;

namespace Ductus.FluentDocker.Services.Impl
{
Expand Down Expand Up @@ -129,14 +130,24 @@ public override void Start()

State = ServiceRunningState.Starting;

var result = host.Host.ComposeUp(_config.AlternativeServiceName, _config.ForceRecreate,
_config.NoRecreate, _config.NoBuild, _config.ForceBuild,
_config.TimeoutSeconds == TimeSpan.Zero ? (TimeSpan?)null : _config.TimeoutSeconds, _config.RemoveOrphans,
_config.UseColor,
true/*noStart*/,
_config.Services,
_config.EnvironmentNameValue,
host.Certificates, _config.ComposeFilePath.ToArray());
var result = host.Host.ComposeUpCommand(
new ComposeUpCommandArgs
{
AltProjectName = _config.AlternativeServiceName,
ForceRecreate = _config.ForceRecreate,
NoRecreate = _config.NoRecreate,
DontBuild = _config.NoBuild,
BuildBeforeCreate = _config.ForceBuild,
Timeout = _config.TimeoutSeconds == TimeSpan.Zero ? (TimeSpan?)null : _config.TimeoutSeconds,
RemoveOrphans = _config.RemoveOrphans,
UseColor = _config.UseColor,
NoStart = true,
Services = _config.Services,
Env = _config.EnvironmentNameValue,
Certificates = host.Certificates,
ComposeFiles = _config.ComposeFilePath.ToArray(),
ProjectDirectory = _config.ProjectDirectory
});

if (!result.Success)
{
Expand All @@ -147,14 +158,24 @@ public override void Start()

State = ServiceRunningState.Starting;

result = host.Host.ComposeUp(_config.AlternativeServiceName,
false/*forceRecreate*/, false/*noRecreate*/, false/*dontBuild*/, false/*buildBeforeCreate*/,
_config.TimeoutSeconds == TimeSpan.Zero ? (TimeSpan?)null : _config.TimeoutSeconds, _config.RemoveOrphans,
_config.UseColor,
false/*noStart*/,
_config.Services,
_config.EnvironmentNameValue,
host.Certificates, _config.ComposeFilePath.ToArray());
result = host.Host.ComposeUpCommand(
new ComposeUpCommandArgs
{
AltProjectName = _config.AlternativeServiceName,
ForceRecreate = false,
NoRecreate = false,
DontBuild = false,
BuildBeforeCreate = false,
Timeout = _config.TimeoutSeconds == TimeSpan.Zero ? (TimeSpan?)null : _config.TimeoutSeconds,
RemoveOrphans = _config.RemoveOrphans,
UseColor = _config.UseColor,
NoStart = false,
Services = _config.Services,
Env = _config.EnvironmentNameValue,
Certificates = host.Certificates,
ComposeFiles = _config.ComposeFilePath.ToArray(),
ProjectDirectory = _config.ProjectDirectory
});

if (!result.Success)
{
Expand Down
26 changes: 26 additions & 0 deletions Examples/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Simple/bin/Debug/netcoreapp3.1/Simple.dll",
"args": [],
"cwd": "${workspaceFolder}/Simple",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
14 changes: 14 additions & 0 deletions Examples/Examples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DockerInDockerLinux", "Dock
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventDriven", "EventDriven\EventDriven.csproj", "{75D101EB-5CE3-457E-8843-76898CB5513B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple", "Simple\Simple.csproj", "{25359F72-CCB4-4373-9857-D0AC45F8510F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -44,5 +46,17 @@ Global
{75D101EB-5CE3-457E-8843-76898CB5513B}.Release|x64.Build.0 = Release|Any CPU
{75D101EB-5CE3-457E-8843-76898CB5513B}.Release|x86.ActiveCfg = Release|Any CPU
{75D101EB-5CE3-457E-8843-76898CB5513B}.Release|x86.Build.0 = Release|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Debug|x64.ActiveCfg = Debug|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Debug|x64.Build.0 = Debug|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Debug|x86.ActiveCfg = Debug|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Debug|x86.Build.0 = Debug|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Release|Any CPU.Build.0 = Release|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Release|x64.ActiveCfg = Release|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Release|x64.Build.0 = Release|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Release|x86.ActiveCfg = Release|Any CPU
{25359F72-CCB4-4373-9857-D0AC45F8510F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Loading

0 comments on commit 23828e2

Please sign in to comment.