Compare commits

...

4 Commits

Author SHA1 Message Date
Ferenc Hammerl
ec6e1e933a Revert "Avastancu/joannaakl/service container error log (#2110)"
This reverts commit 949269104d.
2022-10-04 16:23:37 +00:00
Ferenc Hammerl
c577be6e62 Update releaseVersion 2022-10-04 17:28:24 +02:00
Ferenc Hammerl
3dd27755cf Release notes for 2.298.1 (#2174)
* Fix incorrect template vars to show SHA for WIN-ARM64 (#2171)

* Update releaseNote.md

* Update runnerversion
2022-10-04 17:14:13 +02:00
Francesco Renzi
3b8cfdae4e Update releaseVersion to 2.298.0 2022-10-04 12:18:21 +00:00
7 changed files with 27 additions and 157 deletions

View File

@@ -247,28 +247,28 @@ jobs:
const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(/<RUNNER_VERSION>/g, runnerVersion)
releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-x64-sha}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-arm64-sha}}')
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA>/g, '${{needs.build.outputs.win-arm64-sha}}')
releaseNote = releaseNote.replace(/<OSX_X64_SHA>/g, '${{needs.build.outputs.osx-x64-sha}}')
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA>/g, '${{needs.build.outputs.osx-arm64-sha}}')
releaseNote = releaseNote.replace(/<LINUX_X64_SHA>/g, '${{needs.build.outputs.linux-x64-sha}}')
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA>/g, '${{needs.build.outputs.linux-arm-sha}}')
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA>/g, '${{needs.build.outputs.linux-arm64-sha}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noexternals}}')
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noexternals}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-x64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-arm64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-arm64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-x64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-x64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm-sha-noruntime}}')
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noruntime-noexternals}}')
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noruntime-noexternals}}')
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noruntime-noexternals}}')
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noruntime-noexternals}}')
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime-noexternals}}')
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noruntime-noexternals}}')

View File

@@ -1,7 +1,8 @@
## Features
- Service containers startup error logs are now included in workflow's logs (#2110)
<!-- ## Bugs -->
## Bugs
- Fixed missing SHA for Windows arm64 release archive (#2171)
## Misc
- Added a feature flag to start warning on `save-state` and `set-output` deprecation (#2164)

View File

@@ -1 +1 @@
<Update to ./src/runnerversion when creating release>
2.298.1

View File

@@ -92,8 +92,6 @@ namespace GitHub.Runner.Worker.Container
public bool IsJobContainer { get; set; }
public bool IsAlpine { get; set; }
public bool FailedInitialization { get; set; }
public IDictionary<string, string> ContainerEnvironmentVariables
{
get

View File

@@ -98,41 +98,12 @@ namespace GitHub.Runner.Worker
await StartContainerAsync(executionContext, container);
}
await RunContainersHealthcheck(executionContext, containers);
}
public async Task RunContainersHealthcheck(IExecutionContext executionContext, List<ContainerInfo> containers)
{
executionContext.Output("##[group]Waiting for all services to be ready");
var unhealthyContainers = new List<ContainerInfo>();
foreach (var container in containers.Where(c => !c.IsJobContainer))
{
var healthcheck = await ContainerHealthcheck(executionContext, container);
if (!string.Equals(healthcheck, "healthy", StringComparison.OrdinalIgnoreCase))
{
unhealthyContainers.Add(container);
}
else
{
executionContext.Output($"{container.ContainerNetworkAlias} service is healthy.");
}
await ContainerHealthcheck(executionContext, container);
}
executionContext.Output("##[endgroup]");
if (unhealthyContainers.Count > 0)
{
foreach (var container in unhealthyContainers)
{
executionContext.Output($"##[group]Service container {container.ContainerNetworkAlias} failed.");
await _dockerManager.DockerLogs(context: executionContext, containerId: container.ContainerId);
executionContext.Error($"Failed to initialize container {container.ContainerImage}");
container.FailedInitialization = true;
executionContext.Output("##[endgroup]");
}
throw new InvalidOperationException("One or more containers failed to start.");
}
}
public async Task StopContainersAsync(IExecutionContext executionContext, object data)
@@ -328,8 +299,9 @@ namespace GitHub.Runner.Worker
if (!string.IsNullOrEmpty(container.ContainerId))
{
if (!container.IsJobContainer && !container.FailedInitialization)
if (!container.IsJobContainer)
{
// Print logs for service container jobs (not the "action" job itself b/c that's already logged).
executionContext.Output($"Print service container logs: {container.ContainerDisplayName}");
int logsExitCode = await _dockerManager.DockerLogs(executionContext, container.ContainerId);
@@ -423,14 +395,14 @@ namespace GitHub.Runner.Worker
}
}
private async Task<string> ContainerHealthcheck(IExecutionContext executionContext, ContainerInfo container)
private async Task ContainerHealthcheck(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 String.Empty;
return;
}
var retryCount = 0;
while (string.Equals(serviceHealth, "starting", StringComparison.OrdinalIgnoreCase))
@@ -441,7 +413,14 @@ namespace GitHub.Runner.Worker
serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
retryCount++;
}
return serviceHealth;
if (string.Equals(serviceHealth, "healthy", StringComparison.OrdinalIgnoreCase))
{
executionContext.Output($"{container.ContainerNetworkAlias} service is healthy.");
}
else
{
throw new InvalidOperationException($"Failed to initialize, {container.ContainerNetworkAlias} service is {serviceHealth}.");
}
}
private async Task<string> ContainerRegistryLogin(IExecutionContext executionContext, ContainerInfo container)

View File

@@ -1,108 +0,0 @@
using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Container;
using Xunit;
using Moq;
using GitHub.Runner.Worker.Container.ContainerHooks;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using GitHub.DistributedTask.WebApi;
using System;
namespace GitHub.Runner.Common.Tests.Worker
{
public sealed class ContainerOperationProviderL0
{
private TestHostContext _hc;
private Mock<IExecutionContext> _ec;
private Mock<IDockerCommandManager> _dockerManager;
private Mock<IContainerHookManager> _containerHookManager;
private ContainerOperationProvider containerOperationProvider;
private Mock<IJobServerQueue> serverQueue;
private Mock<IPagingLogger> pagingLogger;
private List<string> healthyDockerStatus = new List<string> { "healthy" };
private List<string> unhealthyDockerStatus = new List<string> { "unhealthy" };
private List<string> dockerLogs = new List<string> { "log1", "log2", "log3" };
List<ContainerInfo> containers = new List<ContainerInfo>();
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async void RunServiceContainersHealthcheck_UnhealthyServiceContainer_AssertFailedTask()
{
//Arrange
Setup();
_dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(unhealthyDockerStatus));
//Act
try
{
await containerOperationProvider.RunContainersHealthcheck(_ec.Object, containers);
}
catch (InvalidOperationException)
{
//Assert
Assert.Equal(TaskResult.Failed, _ec.Object.Result ?? TaskResult.Failed);
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async void RunServiceContainersHealthcheck_UnhealthyServiceContainer_AssertExceptionThrown()
{
//Arrange
Setup();
_dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(unhealthyDockerStatus));
//Act and Assert
await Assert.ThrowsAsync<InvalidOperationException>(() => containerOperationProvider.RunContainersHealthcheck(_ec.Object, containers));
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async void RunServiceContainersHealthcheck_healthyServiceContainer_AssertSucceededTask()
{
//Arrange
Setup();
_dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(healthyDockerStatus));
//Act
await containerOperationProvider.RunContainersHealthcheck(_ec.Object, containers);
//Assert
Assert.Equal(TaskResult.Succeeded, _ec.Object.Result ?? TaskResult.Succeeded);
}
private void Setup([CallerMemberName] string testName = "")
{
containers.Add(new ContainerInfo() { ContainerImage = "ubuntu:16.04" });
_hc = new TestHostContext(this, testName);
_ec = new Mock<IExecutionContext>();
serverQueue = new Mock<IJobServerQueue>();
pagingLogger = new Mock<IPagingLogger>();
_dockerManager = new Mock<IDockerCommandManager>();
_containerHookManager = new Mock<IContainerHookManager>();
containerOperationProvider = new ContainerOperationProvider();
_hc.SetSingleton<IDockerCommandManager>(_dockerManager.Object);
_hc.SetSingleton<IJobServerQueue>(serverQueue.Object);
_hc.SetSingleton<IPagingLogger>(pagingLogger.Object);
_hc.SetSingleton<IDockerCommandManager>(_dockerManager.Object);
_hc.SetSingleton<IContainerHookManager>(_containerHookManager.Object);
_ec.Setup(x => x.Global).Returns(new GlobalContext());
containerOperationProvider.Initialize(_hc);
}
}
}

View File

@@ -1 +1 @@
2.298.0
2.298.1