diff --git a/src/Agent.Worker/ContainerOperationProvider.cs b/src/Agent.Worker/ContainerOperationProvider.cs index 985e45fd56..584e5cc328 100644 --- a/src/Agent.Worker/ContainerOperationProvider.cs +++ b/src/Agent.Worker/ContainerOperationProvider.cs @@ -42,7 +42,13 @@ public override void Initialize(IHostContext hostContext) { base.Initialize(hostContext); _dockerManger = HostContext.GetService(); - _containerNetwork = $"vsts_network_{Guid.NewGuid().ToString("N")}"; + _containerNetwork = $"vsts_network_{Guid.NewGuid():N}"; + } + + private string GetContainerNetwork(IExecutionContext executionContext) + { + var useHostNetwork = AgentKnobs.DockerNetworkCreateDriver.GetValue(executionContext).AsString() == "host"; + return useHostNetwork ? "host" : _containerNetwork; } public async Task StartContainersAsync(IExecutionContext executionContext, object data) @@ -110,8 +116,9 @@ public async Task StartContainersAsync(IExecutionContext executionContext, objec // Create local docker network for this job to avoid port conflict when multiple agents run on same machine. // All containers within a job join the same network - await CreateContainerNetworkAsync(executionContext, _containerNetwork); - containers.ForEach(container => container.ContainerNetwork = _containerNetwork); + var containerNetwork = GetContainerNetwork(executionContext); + await CreateContainerNetworkAsync(executionContext, containerNetwork); + containers.ForEach(container => container.ContainerNetwork = containerNetwork); foreach (var container in containers) { @@ -146,7 +153,8 @@ public async Task StopContainersAsync(IExecutionContext executionContext, object await StopContainerAsync(executionContext, container); } // Remove the container network - await RemoveContainerNetworkAsync(executionContext, _containerNetwork); + var containerNetwork = GetContainerNetwork(executionContext); + await RemoveContainerNetworkAsync(executionContext, containerNetwork); } private async Task GetMSIAccessToken(IExecutionContext executionContext) @@ -793,11 +801,20 @@ private async Task CreateContainerNetworkAsync(IExecutionContext executionContex { Trace.Entering(); ArgUtil.NotNull(executionContext, nameof(executionContext)); - int networkExitCode = await _dockerManger.DockerNetworkCreate(executionContext, network); - if (networkExitCode != 0) + + if (network != "host") + { + int networkExitCode = await _dockerManger.DockerNetworkCreate(executionContext, network); + if (networkExitCode != 0) + { + throw new InvalidOperationException($"Docker network create failed with exit code {networkExitCode}"); + } + } + else { - throw new InvalidOperationException($"Docker network create failed with exit code {networkExitCode}"); + Trace.Info("Skipping creation of a new docker network. Reusing the host network."); } + // Expose docker network to env executionContext.Variables.Set(Constants.Variables.Agent.ContainerNetwork, network); } @@ -808,13 +825,17 @@ private async Task RemoveContainerNetworkAsync(IExecutionContext executionContex ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(network, nameof(network)); - executionContext.Output($"Remove container network: {network}"); - - int removeExitCode = await _dockerManger.DockerNetworkRemove(executionContext, network); - if (removeExitCode != 0) + if (network != "host") { - executionContext.Warning($"Docker network rm failed with exit code {removeExitCode}"); + executionContext.Output($"Remove container network: {network}"); + + int removeExitCode = await _dockerManger.DockerNetworkRemove(executionContext, network); + if (removeExitCode != 0) + { + executionContext.Warning($"Docker network rm failed with exit code {removeExitCode}"); + } } + // Remove docker network from env executionContext.Variables.Set(Constants.Variables.Agent.ContainerNetwork, null); }