Browse Source
* Pull docker images before running - This step also validates that docker is installed before trying to pull and before running so that logic can be removed from the DockerRunner. - Let the application exit if it tye run fails to start. Fixes #222davidfowl/build-earlier
committed by
GitHub
3 changed files with 104 additions and 30 deletions
@ -0,0 +1,91 @@ |
|||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
// See the LICENSE file in the project root for more information.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Tye.Hosting.Model; |
||||
|
|
||||
|
namespace Microsoft.Tye.Hosting |
||||
|
{ |
||||
|
public class DockerImagePuller : IApplicationProcessor |
||||
|
{ |
||||
|
private readonly ILogger _logger; |
||||
|
|
||||
|
public DockerImagePuller(ILogger logger) |
||||
|
{ |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
public async Task StartAsync(Application application) |
||||
|
{ |
||||
|
var images = new HashSet<string>(); |
||||
|
|
||||
|
foreach (var s in application.Services) |
||||
|
{ |
||||
|
if (s.Value.Description.RunInfo is DockerRunInfo docker) |
||||
|
{ |
||||
|
images.Add(docker.Image); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// No images, no docker skip it.
|
||||
|
if (images.Count == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!await DockerDetector.Instance.IsDockerInstalled.Value) |
||||
|
{ |
||||
|
_logger.LogError("Unable to detect docker installation. Docker is not installed."); |
||||
|
|
||||
|
throw new CommandException("Docker is not installed."); |
||||
|
} |
||||
|
|
||||
|
if (!await DockerDetector.Instance.IsDockerConnectedToDaemon.Value) |
||||
|
{ |
||||
|
_logger.LogError("Unable to connect to docker daemon. Docker is not running."); |
||||
|
|
||||
|
throw new CommandException("Docker is not running."); |
||||
|
} |
||||
|
|
||||
|
var tasks = new Task[images.Count]; |
||||
|
var index = 0; |
||||
|
foreach (var image in images) |
||||
|
{ |
||||
|
tasks[index++] = PullContainerAsync(image); |
||||
|
} |
||||
|
|
||||
|
await Task.WhenAll(tasks); |
||||
|
} |
||||
|
|
||||
|
private async Task PullContainerAsync(string image) |
||||
|
{ |
||||
|
await Task.Yield(); |
||||
|
|
||||
|
var command = $"pull {image}"; |
||||
|
|
||||
|
_logger.LogInformation("Running docker command {command}", command); |
||||
|
|
||||
|
var result = await ProcessUtil.RunAsync( |
||||
|
"docker", |
||||
|
command, |
||||
|
outputDataReceived: data => _logger.LogInformation("{Image}: " + data, image), |
||||
|
errorDataReceived: data => _logger.LogInformation("{Image}: " + data, image), |
||||
|
throwOnError: false); |
||||
|
|
||||
|
if (result.ExitCode != 0) |
||||
|
{ |
||||
|
throw new CommandException("Docker pull command failed"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Task StopAsync(Application application) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue