mirror of
https://github.com/actions/runner.git
synced 2025-12-10 12:36:23 +00:00
Compare commits
1 Commits
yaananth-p
...
features/c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b6fb51f7f |
@@ -11,7 +11,7 @@ export RUNNER_CFG_PAT=yourPAT
|
||||
|
||||
## Create running as a service
|
||||
|
||||
**Scenario**: Run on a machine or VM ([not container](#why-cant-i-use-a-container)) which automates:
|
||||
**Scenario**: Run on a machine or VM (not container) which automates:
|
||||
|
||||
- Resolving latest released runner
|
||||
- Download and extract latest
|
||||
@@ -26,13 +26,9 @@ Run as a one-liner. NOTE: replace with yourorg/yourrepo (repo level) or just you
|
||||
curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/create-latest-svc.sh | bash -s yourorg/yourrepo
|
||||
```
|
||||
|
||||
### Why can't I use a container?
|
||||
|
||||
The runner is installed as a service using `systemd` and `systemctl`. Docker does not support `systemd` for service configuration on a container.
|
||||
|
||||
## Uninstall running as service
|
||||
|
||||
**Scenario**: Run on a machine or VM ([not container](#why-cant-i-use-a-container)) which automates:
|
||||
**Scenario**: Run on a machine or VM (not container) which automates:
|
||||
|
||||
- Stops and uninstalls the systemd (linux) or Launchd (osx) service
|
||||
- Acquires a removal token
|
||||
|
||||
@@ -73,4 +73,4 @@ if [ "${runner_plat}" == "linux" ]; then
|
||||
fi
|
||||
${prefix}./svc.sh stop
|
||||
${prefix}./svc.sh uninstall
|
||||
./config.sh remove --token $REMOVE_TOKEN
|
||||
${prefix}./config.sh remove --token $REMOVE_TOKEN
|
||||
|
||||
@@ -124,7 +124,7 @@ function status()
|
||||
echo
|
||||
echo "not installed"
|
||||
echo
|
||||
exit 1
|
||||
return
|
||||
fi
|
||||
|
||||
systemctl --no-pager status ${SVC_NAME}
|
||||
|
||||
@@ -24,10 +24,10 @@ if /i "%~1" equ "localRun" (
|
||||
rem ********************************************************************************
|
||||
"%~dp0bin\Runner.Listener.exe" run %*
|
||||
|
||||
rem Return code 4 means the run once runner received an update message.
|
||||
rem Return codes 3 and 4 mean the runner received an update message.
|
||||
rem Sleep 5 seconds to wait for the update process finish and run the runner again.
|
||||
if ERRORLEVEL 4 (
|
||||
if ERRORLEVEL 3 (
|
||||
timeout /t 5 /nobreak > NUL
|
||||
"%~dp0bin\Runner.Listener.exe" run %*
|
||||
"%~dp0run.cmd" %*
|
||||
)
|
||||
)
|
||||
|
||||
@@ -396,7 +396,14 @@ namespace GitHub.Runner.Listener
|
||||
autoUpdateInProgress = true;
|
||||
var runnerUpdateMessage = JsonUtility.FromString<AgentRefreshMessage>(message.Body);
|
||||
var selfUpdater = HostContext.GetService<ISelfUpdater>();
|
||||
selfUpdateTask = selfUpdater.SelfUpdate(runnerUpdateMessage, jobDispatcher, !runOnce && HostContext.StartupType != StartupType.Service, HostContext.RunnerShutdownToken);
|
||||
|
||||
#if OS_WINDOWS
|
||||
var restartInteractiveRunner = false;
|
||||
#else
|
||||
var restartInteractiveRunner = !runOnce;
|
||||
#endif
|
||||
|
||||
selfUpdateTask = selfUpdater.SelfUpdate(runnerUpdateMessage, jobDispatcher, restartInteractiveRunner, HostContext.RunnerShutdownToken);
|
||||
Trace.Info("Refresh message received, kick-off selfupdate background process.");
|
||||
}
|
||||
else
|
||||
|
||||
@@ -471,12 +471,12 @@ namespace GitHub.Runner.Worker
|
||||
executionContext.Output($"##[group]Pull down action image '{setupInfo.Container.Image}'");
|
||||
|
||||
// Pull down docker image with retry up to 3 times
|
||||
var dockerManager = HostContext.GetService<IDockerCommandManager>();
|
||||
var dockerManger = HostContext.GetService<IDockerCommandManager>();
|
||||
int retryCount = 0;
|
||||
int pullExitCode = 0;
|
||||
while (retryCount < 3)
|
||||
{
|
||||
pullExitCode = await dockerManager.DockerPull(executionContext, setupInfo.Container.Image);
|
||||
pullExitCode = await dockerManger.DockerPull(executionContext, setupInfo.Container.Image);
|
||||
if (pullExitCode == 0)
|
||||
{
|
||||
break;
|
||||
@@ -515,13 +515,13 @@ namespace GitHub.Runner.Worker
|
||||
executionContext.Output($"##[group]Build container for action use: '{setupInfo.Container.Dockerfile}'.");
|
||||
|
||||
// Build docker image with retry up to 3 times
|
||||
var dockerManager = HostContext.GetService<IDockerCommandManager>();
|
||||
var dockerManger = HostContext.GetService<IDockerCommandManager>();
|
||||
int retryCount = 0;
|
||||
int buildExitCode = 0;
|
||||
var imageName = $"{dockerManager.DockerInstanceLabel}:{Guid.NewGuid().ToString("N")}";
|
||||
var imageName = $"{dockerManger.DockerInstanceLabel}:{Guid.NewGuid().ToString("N")}";
|
||||
while (retryCount < 3)
|
||||
{
|
||||
buildExitCode = await dockerManager.DockerBuild(
|
||||
buildExitCode = await dockerManger.DockerBuild(
|
||||
executionContext,
|
||||
setupInfo.Container.WorkingDirectory,
|
||||
setupInfo.Container.Dockerfile,
|
||||
|
||||
@@ -24,12 +24,12 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
public class ContainerOperationProvider : RunnerService, IContainerOperationProvider
|
||||
{
|
||||
private IDockerCommandManager _dockerManager;
|
||||
private IDockerCommandManager _dockerManger;
|
||||
|
||||
public override void Initialize(IHostContext hostContext)
|
||||
{
|
||||
base.Initialize(hostContext);
|
||||
_dockerManager = HostContext.GetService<IDockerCommandManager>();
|
||||
_dockerManger = HostContext.GetService<IDockerCommandManager>();
|
||||
}
|
||||
|
||||
public async Task StartContainersAsync(IExecutionContext executionContext, object data)
|
||||
@@ -92,7 +92,7 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
// Check docker client/server version
|
||||
executionContext.Output("##[group]Checking docker version");
|
||||
DockerVersion dockerVersion = await _dockerManager.DockerVersion(executionContext);
|
||||
DockerVersion dockerVersion = await _dockerManger.DockerVersion(executionContext);
|
||||
executionContext.Output("##[endgroup]");
|
||||
|
||||
ArgUtil.NotNull(dockerVersion.ServerVersion, nameof(dockerVersion.ServerVersion));
|
||||
@@ -106,26 +106,26 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
if (dockerVersion.ServerVersion < requiredDockerEngineAPIVersion)
|
||||
{
|
||||
throw new NotSupportedException($"Min required docker engine API server version is '{requiredDockerEngineAPIVersion}', your docker ('{_dockerManager.DockerPath}') server version is '{dockerVersion.ServerVersion}'");
|
||||
throw new NotSupportedException($"Min required docker engine API server version is '{requiredDockerEngineAPIVersion}', your docker ('{_dockerManger.DockerPath}') server version is '{dockerVersion.ServerVersion}'");
|
||||
}
|
||||
if (dockerVersion.ClientVersion < requiredDockerEngineAPIVersion)
|
||||
{
|
||||
throw new NotSupportedException($"Min required docker engine API client version is '{requiredDockerEngineAPIVersion}', your docker ('{_dockerManager.DockerPath}') client version is '{dockerVersion.ClientVersion}'");
|
||||
throw new NotSupportedException($"Min required docker engine API client version is '{requiredDockerEngineAPIVersion}', your docker ('{_dockerManger.DockerPath}') client version is '{dockerVersion.ClientVersion}'");
|
||||
}
|
||||
|
||||
// Clean up containers left by previous runs
|
||||
executionContext.Output("##[group]Clean up resources from previous jobs");
|
||||
var staleContainers = await _dockerManager.DockerPS(executionContext, $"--all --quiet --no-trunc --filter \"label={_dockerManager.DockerInstanceLabel}\"");
|
||||
var staleContainers = await _dockerManger.DockerPS(executionContext, $"--all --quiet --no-trunc --filter \"label={_dockerManger.DockerInstanceLabel}\"");
|
||||
foreach (var staleContainer in staleContainers)
|
||||
{
|
||||
int containerRemoveExitCode = await _dockerManager.DockerRemove(executionContext, staleContainer);
|
||||
int containerRemoveExitCode = await _dockerManger.DockerRemove(executionContext, staleContainer);
|
||||
if (containerRemoveExitCode != 0)
|
||||
{
|
||||
executionContext.Warning($"Delete stale containers failed, docker rm fail with exit code {containerRemoveExitCode} for container {staleContainer}");
|
||||
}
|
||||
}
|
||||
|
||||
int networkPruneExitCode = await _dockerManager.DockerNetworkPrune(executionContext);
|
||||
int networkPruneExitCode = await _dockerManger.DockerNetworkPrune(executionContext);
|
||||
if (networkPruneExitCode != 0)
|
||||
{
|
||||
executionContext.Warning($"Delete stale container networks failed, docker network prune fail with exit code {networkPruneExitCode}");
|
||||
@@ -208,7 +208,7 @@ namespace GitHub.Runner.Worker
|
||||
int pullExitCode = 0;
|
||||
while (retryCount < 3)
|
||||
{
|
||||
pullExitCode = await _dockerManager.DockerPull(executionContext, container.ContainerImage, configLocation);
|
||||
pullExitCode = await _dockerManger.DockerPull(executionContext, container.ContainerImage, configLocation);
|
||||
if (pullExitCode == 0)
|
||||
{
|
||||
break;
|
||||
@@ -266,11 +266,11 @@ namespace GitHub.Runner.Worker
|
||||
container.ContainerEntryPointArgs = "\"-f\" \"/dev/null\"";
|
||||
}
|
||||
|
||||
container.ContainerId = await _dockerManager.DockerCreate(executionContext, container);
|
||||
container.ContainerId = await _dockerManger.DockerCreate(executionContext, container);
|
||||
ArgUtil.NotNullOrEmpty(container.ContainerId, nameof(container.ContainerId));
|
||||
|
||||
// Start container
|
||||
int startExitCode = await _dockerManager.DockerStart(executionContext, container.ContainerId);
|
||||
int startExitCode = await _dockerManger.DockerStart(executionContext, container.ContainerId);
|
||||
if (startExitCode != 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Docker start fail with exit code {startExitCode}");
|
||||
@@ -279,12 +279,12 @@ namespace GitHub.Runner.Worker
|
||||
try
|
||||
{
|
||||
// Make sure container is up and running
|
||||
var psOutputs = await _dockerManager.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --filter status=running --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\"");
|
||||
var psOutputs = await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --filter status=running --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\"");
|
||||
if (psOutputs.FirstOrDefault(x => !string.IsNullOrEmpty(x))?.StartsWith(container.ContainerId) != true)
|
||||
{
|
||||
// container is not up and running, pull docker log for this container.
|
||||
await _dockerManager.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\"");
|
||||
int logsExitCode = await _dockerManager.DockerLogs(executionContext, container.ContainerId);
|
||||
await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\"");
|
||||
int logsExitCode = await _dockerManger.DockerLogs(executionContext, container.ContainerId);
|
||||
if (logsExitCode != 0)
|
||||
{
|
||||
executionContext.Warning($"Docker logs fail with exit code {logsExitCode}");
|
||||
@@ -309,7 +309,7 @@ namespace GitHub.Runner.Worker
|
||||
["ports"] = new DictionaryContextData(),
|
||||
["network"] = new StringContextData(container.ContainerNetwork)
|
||||
};
|
||||
container.AddPortMappings(await _dockerManager.DockerPort(executionContext, container.ContainerId));
|
||||
container.AddPortMappings(await _dockerManger.DockerPort(executionContext, container.ContainerId));
|
||||
foreach (var port in container.PortMappings)
|
||||
{
|
||||
(service["ports"] as DictionaryContextData)[port.ContainerPort] = new StringContextData(port.HostPort);
|
||||
@@ -319,7 +319,7 @@ namespace GitHub.Runner.Worker
|
||||
else
|
||||
{
|
||||
var configEnvFormat = "--format \"{{range .Config.Env}}{{println .}}{{end}}\"";
|
||||
var containerEnv = await _dockerManager.DockerInspect(executionContext, container.ContainerId, configEnvFormat);
|
||||
var containerEnv = await _dockerManger.DockerInspect(executionContext, container.ContainerId, configEnvFormat);
|
||||
container.ContainerRuntimePath = DockerUtil.ParsePathFromConfigEnv(containerEnv);
|
||||
executionContext.JobContext.Container["id"] = new StringContextData(container.ContainerId);
|
||||
}
|
||||
@@ -336,7 +336,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
executionContext.Output($"Stop and remove container: {container.ContainerDisplayName}");
|
||||
|
||||
int rmExitCode = await _dockerManager.DockerRemove(executionContext, container.ContainerId);
|
||||
int rmExitCode = await _dockerManger.DockerRemove(executionContext, container.ContainerId);
|
||||
if (rmExitCode != 0)
|
||||
{
|
||||
executionContext.Warning($"Docker rm fail with exit code {rmExitCode}");
|
||||
@@ -396,7 +396,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
Trace.Entering();
|
||||
ArgUtil.NotNull(executionContext, nameof(executionContext));
|
||||
int networkExitCode = await _dockerManager.DockerNetworkCreate(executionContext, network);
|
||||
int networkExitCode = await _dockerManger.DockerNetworkCreate(executionContext, network);
|
||||
if (networkExitCode != 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Docker network create failed with exit code {networkExitCode}");
|
||||
@@ -411,7 +411,7 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
executionContext.Output($"Remove container network: {network}");
|
||||
|
||||
int removeExitCode = await _dockerManager.DockerNetworkRemove(executionContext, network);
|
||||
int removeExitCode = await _dockerManger.DockerNetworkRemove(executionContext, network);
|
||||
if (removeExitCode != 0)
|
||||
{
|
||||
executionContext.Warning($"Docker network rm failed with exit code {removeExitCode}");
|
||||
@@ -421,7 +421,7 @@ namespace GitHub.Runner.Worker
|
||||
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();
|
||||
string serviceHealth = (await _dockerManger.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(serviceHealth))
|
||||
{
|
||||
// Container has no HEALTHCHECK
|
||||
@@ -433,7 +433,7 @@ namespace GitHub.Runner.Worker
|
||||
TimeSpan backoff = BackoffTimerHelper.GetExponentialBackoff(retryCount, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(32), TimeSpan.FromSeconds(2));
|
||||
executionContext.Output($"{container.ContainerNetworkAlias} service is starting, waiting {backoff.Seconds} seconds before checking again.");
|
||||
await Task.Delay(backoff, executionContext.CancellationToken);
|
||||
serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
||||
serviceHealth = (await _dockerManger.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
||||
retryCount++;
|
||||
}
|
||||
if (string.Equals(serviceHealth, "healthy", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -462,7 +462,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to create directory to store registry client credentials: {e.Message}");
|
||||
}
|
||||
var loginExitCode = await _dockerManager.DockerLogin(
|
||||
var loginExitCode = await _dockerManger.DockerLogin(
|
||||
executionContext,
|
||||
configLocation,
|
||||
container.RegistryServer,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
@@ -37,7 +37,7 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
// Update the env dictionary.
|
||||
AddInputsToEnvironment();
|
||||
|
||||
var dockerManager = HostContext.GetService<IDockerCommandManager>();
|
||||
var dockerManger = HostContext.GetService<IDockerCommandManager>();
|
||||
|
||||
// container image haven't built/pull
|
||||
if (Data.Image.StartsWith("docker://", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -52,8 +52,8 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
|
||||
ExecutionContext.Output($"##[group]Building docker image");
|
||||
ExecutionContext.Output($"Dockerfile for action: '{dockerFile}'.");
|
||||
var imageName = $"{dockerManager.DockerInstanceLabel}:{ExecutionContext.Id.ToString("N")}";
|
||||
var buildExitCode = await dockerManager.DockerBuild(
|
||||
var imageName = $"{dockerManger.DockerInstanceLabel}:{ExecutionContext.Id.ToString("N")}";
|
||||
var buildExitCode = await dockerManger.DockerBuild(
|
||||
ExecutionContext,
|
||||
ExecutionContext.GetGitHubContext("workspace"),
|
||||
dockerFile,
|
||||
@@ -209,7 +209,7 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
using (var stdoutManager = new OutputManager(ExecutionContext, ActionCommandManager, container))
|
||||
using (var stderrManager = new OutputManager(ExecutionContext, ActionCommandManager, container))
|
||||
{
|
||||
var runExitCode = await dockerManager.DockerRun(ExecutionContext, container, stdoutManager.OnDataReceived, stderrManager.OnDataReceived);
|
||||
var runExitCode = await dockerManger.DockerRun(ExecutionContext, container, stdoutManager.OnDataReceived, stderrManager.OnDataReceived);
|
||||
ExecutionContext.Debug($"Docker Action run completed with exit code {runExitCode}");
|
||||
if (runExitCode != 0)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,6 @@ namespace GitHub.Runner.Worker
|
||||
Trace.Info("Message received.");
|
||||
ArgUtil.Equal(MessageType.NewJobRequest, channelMessage.MessageType, nameof(channelMessage.MessageType));
|
||||
ArgUtil.NotNullOrEmpty(channelMessage.Body, nameof(channelMessage.Body));
|
||||
Trace.Info(channelMessage.Body);
|
||||
var jobMessage = StringUtil.ConvertFromJson<Pipelines.AgentJobRequestMessage>(channelMessage.Body);
|
||||
ArgUtil.NotNull(jobMessage, nameof(jobMessage));
|
||||
HostContext.WritePerfCounter($"WorkerJobMessageReceived_{jobMessage.RequestId.ToString()}");
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<WriteLinesToFile File="Runner.Sdk/BuildConstants.cs" Lines="@(BuildConstants)" Overwrite="true" />
|
||||
|
||||
<Exec Command="git update-index --assume-unchanged ./Runner.Sdk/BuildConstants.cs" ConsoleToMSBuild="true" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user