public static async Task <string> WrapInBuildEnvAsync(this RemoteProcessStartInfo info, IOperationExecutionContext context, string imageName, bool shareCache, bool allowNetwork = false, bool forceASLR = true, params string[] additionalPaths) { var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>(); var executionBaseDir = await context.GetExecutionBaseDirAsync(); var volumes = string.Join(" ", new[] { executionBaseDir }.Concat(additionalPaths) .Select(s => fileOps.CombinePath(info.WorkingDirectory, s)) .Select(s => "-v " + $"{s}:{s.Replace($"_E{context.ExecutionId}", "_E0")}".EscapeLinuxArg()) .Concat(new[] { "-v " + string.Format("{0}:{0}:ro", (await DFHackCacheVariableFunction.GetAsync(context))).EscapeLinuxArg(), shareCache ? "-v \"/home/buildmaster/.ccache:/home/buildmaster/.ccache\"" : $"-v \"/home/buildmaster/.ccache:/home/buildmaster/.ccache:ro\" -e CCACHE_READONLY=1 -e CCACHE_TEMPDIR=\"/home/buildmaster/.ccache_temp\" -v {fileOps.CombinePath(executionBaseDir, ".ccache").EscapeLinuxArg()}\":/home/buildmaster/.ccache_temp\"" }) ); var network = allowNetwork ? string.Empty : "--network none"; var security = string.Empty; if (!forceASLR) { // Store seccomp.json outside of the execution directory root so the image cannot modify it. var seccompPath = fileOps.CombinePath(executionBaseDir, "..", "docker-seccomp.json"); using (var output = await fileOps.OpenFileAsync(seccompPath, FileMode.Create, FileAccess.Write)) using (var input = typeof(Utils).Assembly.GetManifestResourceStream("Inedo.Extensions.DFHack.docker-seccomp.json")) { await input.CopyToAsync(output); } security = "--security-opt seccomp=" + seccompPath.EscapeLinuxArg(); } var env = string.Join(" ", info.EnvironmentVariables .Concat(new[] { new KeyValuePair <string, string>("CCACHE_BASEDIR", executionBaseDir.Replace($"_E{context.ExecutionId}", "_E0")) }) .Select(kv => $"-e {kv.Key.EscapeLinuxArg()}={kv.Value.EscapeLinuxArg()}")); info.EnvironmentVariables.Clear(); var cidfile = fileOps.CombinePath(executionBaseDir, "cid-" + Guid.NewGuid().ToString("N")); info.Arguments = $"run --rm {env} {volumes} {network} {security} --cidfile {cidfile.EscapeLinuxArg()} -w {info.WorkingDirectory.Replace($"_E{context.ExecutionId}", "_E0").EscapeLinuxArg()} -e CCACHE_DIR=\"/home/buildmaster/.ccache\" -u $(id -u):$(id -g) {imageName.EscapeLinuxArg()} {info.FileName.EscapeLinuxArg()} {info.Arguments}"; info.FileName = "/usr/bin/docker"; return(cidfile); }