From 3b4406161b259fe5f4b433ac08cfdb8ca9afd059 Mon Sep 17 00:00:00 2001 From: Ava S Date: Tue, 30 Aug 2022 12:17:35 +0200 Subject: [PATCH] adding support for a service container docker logs --- .../Container/DockerCommandManager.cs | 6 +++ .../ContainerOperationProvider.cs | 16 +++++-- .../L0/Worker/ContainerOperationProviderL0.cs | 44 +++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 src/Test/L0/Worker/ContainerOperationProviderL0.cs diff --git a/src/Runner.Worker/Container/DockerCommandManager.cs b/src/Runner.Worker/Container/DockerCommandManager.cs index a0c158bdf..265cafc75 100644 --- a/src/Runner.Worker/Container/DockerCommandManager.cs +++ b/src/Runner.Worker/Container/DockerCommandManager.cs @@ -32,6 +32,7 @@ namespace GitHub.Runner.Worker.Container Task DockerExec(IExecutionContext context, string containerId, string options, string command); Task DockerExec(IExecutionContext context, string containerId, string options, string command, List outputs); Task> DockerInspect(IExecutionContext context, string dockerObject, string options); + Task> DockerInspectLogs(IExecutionContext context, string dockerContainerId); Task> DockerPort(IExecutionContext context, string containerId); Task DockerLogin(IExecutionContext context, string configFileDirectory, string registry, string username, string password); } @@ -352,6 +353,11 @@ namespace GitHub.Runner.Worker.Container return await ExecuteDockerCommandAsync(context, "inspect", $"{options} {dockerObject}"); } + public async Task> DockerInspectLogs(IExecutionContext context, string dockerContainerId) + { + return await ExecuteDockerCommandAsync(context, "logs", $"{dockerContainerId}"); + } + public async Task> DockerPort(IExecutionContext context, string containerId) { List portMappingLines = await ExecuteDockerCommandAsync(context, "port", containerId); diff --git a/src/Runner.Worker/ContainerOperationProvider.cs b/src/Runner.Worker/ContainerOperationProvider.cs index 73472795c..0b15d54c6 100644 --- a/src/Runner.Worker/ContainerOperationProvider.cs +++ b/src/Runner.Worker/ContainerOperationProvider.cs @@ -101,7 +101,8 @@ namespace GitHub.Runner.Worker executionContext.Output("##[group]Waiting for all services to be ready"); foreach (var container in containers.Where(c => !c.IsJobContainer)) { - await ContainerHealthcheck(executionContext, container); + var healthcheck = await Healthcheck(executionContext, container); + await ContainerHealthcheckLogs(executionContext, container, healthcheck); } executionContext.Output("##[endgroup]"); } @@ -395,14 +396,13 @@ namespace GitHub.Runner.Worker } } - private async Task ContainerHealthcheck(IExecutionContext executionContext, ContainerInfo container) - { + private async Task Healthcheck(IExecutionContext executionContext, ContainerInfo container){ string healthCheck = "--format=\"{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}\""; string serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault(); if (string.IsNullOrEmpty(serviceHealth)) { // Container has no HEALTHCHECK - return; + return String.Empty; } var retryCount = 0; while (string.Equals(serviceHealth, "starting", StringComparison.OrdinalIgnoreCase)) @@ -413,12 +413,20 @@ namespace GitHub.Runner.Worker serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault(); retryCount++; } + return serviceHealth; + } + + private async Task ContainerHealthcheckLogs(IExecutionContext executionContext, ContainerInfo container, string serviceHealth) + { + if (string.Equals(serviceHealth, "healthy", StringComparison.OrdinalIgnoreCase)) { executionContext.Output($"{container.ContainerNetworkAlias} service is healthy."); } else { + List dockerLogs = await _dockerManager.DockerInspectLogs(context: executionContext, dockerContainerId: container.ContainerId); + dockerLogs.ForEach(log => executionContext.Output(log)); throw new InvalidOperationException($"Failed to initialize, {container.ContainerNetworkAlias} service is {serviceHealth}."); } } diff --git a/src/Test/L0/Worker/ContainerOperationProviderL0.cs b/src/Test/L0/Worker/ContainerOperationProviderL0.cs new file mode 100644 index 000000000..f4df2c83a --- /dev/null +++ b/src/Test/L0/Worker/ContainerOperationProviderL0.cs @@ -0,0 +1,44 @@ +using System; +using GitHub.Runner.Worker; +using GitHub.Runner.Worker.Container; +using Moq; +using Xunit; + +namespace GitHub.Runner.Common.Tests.Worker +{ + public sealed class ContainerOperationProviderL0 + { + // private Mock _commandManager; + // private ContainerOperationProvider operationProvider; + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void EnablePluginInternalCommand() + { + + // _ec.Setup(x => x.Write(It.IsAny(), It.IsAny())) + // .Returns((string tag, string line) => + // { + // hc.GetTrace().Info($"{tag} {line}"); + // return 1; + // }); + // _ec.Setup(x => x.AddIssue(It.IsAny(), It.IsAny())) + // .Callback((Issue issue, string message) => + // { + // hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}"); + // }); + + // _commandManager.EnablePluginInternalCommand(); + + // Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null)); + + // _pipelineDirectoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once); + + } + // private TestHostContext CreateTestContext([CallerMemberName] string testName = "") { + // return null; + // } + + } +} \ No newline at end of file