Skip to content

Commit 23826db

Browse files
Making Node24 changes in the ContainerOperationProviderEnhanced.cs file (#5419)
* Making Node24 changes in the ContainerOperationProviderEnhanced.cs file * Minor fixes * Minor fix * reverting the previous change * Removing unnecessary knob sources * Minor changes * Adding the runtimeknobsource
1 parent 4987764 commit 23826db

File tree

3 files changed

+90
-14
lines changed

3 files changed

+90
-14
lines changed

src/Agent.Sdk/Knob/AgentKnobs.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,8 +745,9 @@ public class AgentKnobs
745745
public static readonly Knob UseNode24ToStartContainer = new Knob(
746746
nameof(UseNode24ToStartContainer),
747747
"If true, try to start container job using Node24, then fallback to Node20, then Node16.",
748-
new RuntimeKnobSource("AZP_AGENT_USE_NODE24_TO_START_CONTAINER"),
749748
new PipelineFeatureSource("UseNode24ToStartContainer"),
749+
new RuntimeKnobSource("AZP_AGENT_USE_NODE24_TO_START_CONTAINER"),
750+
new EnvironmentKnobSource("AZP_AGENT_USE_NODE24_TO_START_CONTAINER"),
750751
new BuiltInDefaultKnobSource("false"));
751752

752753
public static readonly Knob EnableNewMaskerAndRegexes = new Knob(

src/Agent.Worker/ContainerOperationProvider.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,21 +648,30 @@ string useDoubleQuotes(string value)
648648
}
649649
else if (logLine.Contains(labelContainerStartupUsingNode20))
650650
{
651-
executionContext.Debug("Using Node 20 for container startup.");
651+
string warningMsg = useNode24ToStartContainer
652+
? "Cannot run Node 24 in container. Falling back to Node 20 for container startup."
653+
: "Using Node 20 for container startup.";
654+
executionContext.Warning(warningMsg);
652655
containerStartupCompleted = true;
653656
container.ResultNodePath = node20ContainerPath;
654657
break;
655658
}
656659
else if (logLine.Contains(labelContainerStartupUsingNode16))
657660
{
658-
executionContext.Warning("Can not run Node 20 in container. Falling back to Node 16 for container startup.");
661+
string warningMsg = useNode24ToStartContainer
662+
? "Cannot run Node 24 and Node 20 in container. Falling back to Node 16 for container startup."
663+
: "Cannot run Node 20 in container. Falling back to Node 16 for container startup.";
664+
executionContext.Warning(warningMsg);
659665
containerStartupCompleted = true;
660666
container.ResultNodePath = node16ContainerPath;
661667
break;
662668
}
663669
else if (logLine.Contains(labelContainerStartupFailed))
664670
{
665-
executionContext.Error("Can not run both Node 20 and Node 16 in container. Container startup failed.");
671+
string errorMsg = useNode24ToStartContainer
672+
? "Cannot run Node 24, Node 20, and Node 16 in container. Container startup failed."
673+
: "Cannot run both Node 20 and Node 16 in container. Container startup failed.";
674+
executionContext.Error(errorMsg);
666675
containerStartupCompleted = true;
667676
break;
668677
}

src/Agent.Worker/ContainerOperationProviderEnhanced.cs

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,10 @@ private async Task StartContainerAsync(IExecutionContext executionContext, Conta
648648
trace.Info($"Configured {container.MountVolumes.Count} volume mounts: {string.Join(", ", mountSummary)}");
649649

650650
bool useNode20ToStartContainer = AgentKnobs.UseNode20ToStartContainer.GetValue(executionContext).AsBoolean();
651+
bool useNode24ToStartContainer = AgentKnobs.UseNode24ToStartContainer.GetValue(executionContext).AsBoolean();
651652
bool useAgentNode = false;
652653

654+
string labelContainerStartupUsingNode24 = "container-startup-using-node-24";
653655
string labelContainerStartupUsingNode20 = "container-startup-using-node-20";
654656
string labelContainerStartupUsingNode16 = "container-startup-using-node-16";
655657
string labelContainerStartupFailed = "container-startup-failed";
@@ -662,6 +664,7 @@ string containerNodePath(string nodeFolder)
662664
string nodeContainerPath = containerNodePath(NodeHandler.NodeFolder);
663665
string node16ContainerPath = containerNodePath(NodeHandler.Node16Folder);
664666
string node20ContainerPath = containerNodePath(NodeHandler.Node20_1Folder);
667+
string node24ContainerPath = containerNodePath(NodeHandler.Node24Folder);
665668

666669
if (container.IsJobContainer)
667670
{
@@ -697,9 +700,22 @@ string useDoubleQuotes(string value)
697700
else
698701
{
699702
useAgentNode = true;
700-
trace.Info($"Using agent-provided Node.js. Node20 enabled: {useNode20ToStartContainer}");
701-
trace.Info($"Node paths - Default: {nodeContainerPath}, Node16: {node16ContainerPath}, Node20: {node20ContainerPath}");
702-
string sleepCommand = useNode20ToStartContainer ? $"'{node20ContainerPath}' --version && echo '{labelContainerStartupUsingNode20}' && {nodeSetInterval(node20ContainerPath)} || '{node16ContainerPath}' --version && echo '{labelContainerStartupUsingNode16}' && {nodeSetInterval(node16ContainerPath)} || echo '{labelContainerStartupFailed}'" : nodeSetInterval(nodeContainerPath);
703+
trace.Info($"Using agent-provided Node.js. Node20 enabled: {useNode20ToStartContainer}, Node24 enabled: {useNode24ToStartContainer}");
704+
trace.Info($"Node paths - Default: {nodeContainerPath}, Node16: {node16ContainerPath}, Node20: {node20ContainerPath}, Node24: {node24ContainerPath}");
705+
string sleepCommand;
706+
707+
if (useNode24ToStartContainer)
708+
{
709+
sleepCommand = $"'{node24ContainerPath}' --version && echo '{labelContainerStartupUsingNode24}' && {nodeSetInterval(node24ContainerPath)} || '{node20ContainerPath}' --version && echo '{labelContainerStartupUsingNode20}' && {nodeSetInterval(node20ContainerPath)} || '{node16ContainerPath}' --version && echo '{labelContainerStartupUsingNode16}' && {nodeSetInterval(node16ContainerPath)} || echo '{labelContainerStartupFailed}'";
710+
}
711+
else if (useNode20ToStartContainer)
712+
{
713+
sleepCommand = $"'{node20ContainerPath}' --version && echo '{labelContainerStartupUsingNode20}' && {nodeSetInterval(node20ContainerPath)} || '{node16ContainerPath}' --version && echo '{labelContainerStartupUsingNode16}' && {nodeSetInterval(node16ContainerPath)} || echo '{labelContainerStartupFailed}'";
714+
}
715+
else
716+
{
717+
sleepCommand = nodeSetInterval(nodeContainerPath);
718+
}
703719
container.ContainerCommand = PlatformUtil.RunningOnWindows ? $"cmd.exe /c call {useDoubleQuotes(sleepCommand)}" : $"bash -c \"{sleepCommand}\"";
704720
container.ResultNodePath = nodeContainerPath;
705721
}
@@ -762,7 +778,7 @@ string useDoubleQuotes(string value)
762778

763779
executionContext.Warning($"Docker container {container.ContainerId} is not in running state.");
764780
}
765-
else if (useAgentNode && useNode20ToStartContainer)
781+
else if (useAgentNode && (useNode20ToStartContainer || useNode24ToStartContainer))
766782
{
767783
bool containerStartupCompleted = false;
768784
int containerStartupTimeoutInMilliseconds = 10000;
@@ -777,23 +793,39 @@ string useDoubleQuotes(string value)
777793

778794
foreach (string logLine in containerLogs)
779795
{
780-
if (logLine.Contains(labelContainerStartupUsingNode20))
796+
if (logLine.Contains(labelContainerStartupUsingNode24))
781797
{
782-
executionContext.Debug("Using Node 20 for container startup.");
798+
executionContext.Debug("Using Node 24 for container startup.");
799+
containerStartupCompleted = true;
800+
container.ResultNodePath = node24ContainerPath;
801+
break;
802+
}
803+
else if (logLine.Contains(labelContainerStartupUsingNode20))
804+
{
805+
string warningMsg = useNode24ToStartContainer
806+
? "Cannot run Node 24 in container. Falling back to Node 20 for container startup."
807+
: "Using Node 20 for container startup.";
808+
executionContext.Warning(warningMsg);
783809
containerStartupCompleted = true;
784810
container.ResultNodePath = node20ContainerPath;
785811
break;
786812
}
787813
else if (logLine.Contains(labelContainerStartupUsingNode16))
788814
{
789-
executionContext.Warning("Can not run Node 20 in container. Falling back to Node 16 for container startup.");
815+
string warningMsg = useNode24ToStartContainer
816+
? "Cannot run Node 24 and Node 20 in container. Falling back to Node 16 for container startup."
817+
: "Cannot run Node 20 in container. Falling back to Node 16 for container startup.";
818+
executionContext.Warning(warningMsg);
790819
containerStartupCompleted = true;
791820
container.ResultNodePath = node16ContainerPath;
792821
break;
793822
}
794823
else if (logLine.Contains(labelContainerStartupFailed))
795824
{
796-
executionContext.Error("Can not run both Node 20 and Node 16 in container. Container startup failed.");
825+
string errorMsg = useNode24ToStartContainer
826+
? "Cannot run Node 24, Node 20, and Node 16 in container. Container startup failed."
827+
: "Cannot run both Node 20 and Node 16 in container. Container startup failed.";
828+
executionContext.Error(errorMsg);
797829
containerStartupCompleted = true;
798830
break;
799831
}
@@ -1114,8 +1146,30 @@ string useDoubleQuotes(string value)
11141146
if (PlatformUtil.RunningOnLinux)
11151147
{
11161148
bool useNode20InUnsupportedSystem = AgentKnobs.UseNode20InUnsupportedSystem.GetValue(executionContext).AsBoolean();
1149+
bool useNode24InUnsupportedSystem = AgentKnobs.UseNode24InUnsupportedSystem.GetValue(executionContext).AsBoolean();
1150+
1151+
if (!useNode24InUnsupportedSystem)
1152+
{
1153+
var node24 = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), NodeHandler.Node24Folder, "bin", $"node{IOUtil.ExeExtension}"));
1154+
1155+
string node24TestCmd = $"bash -c \"{node24} -v\"";
1156+
List<string> node24VersionOutput = await DockerExec(executionContext, container.ContainerId, node24TestCmd, noExceptionOnError: true);
1157+
1158+
container.NeedsNode20Redirect = WorkerUtilities.IsCommandResultGlibcError(executionContext, node24VersionOutput, out string node24InfoLine);
11171159

1118-
if (!useNode20InUnsupportedSystem)
1160+
if (container.NeedsNode20Redirect)
1161+
{
1162+
PublishTelemetry(
1163+
executionContext,
1164+
new Dictionary<string, string>
1165+
{
1166+
{ "ContainerNode24to20Fallback", container.NeedsNode20Redirect.ToString() }
1167+
}
1168+
);
1169+
}
1170+
}
1171+
1172+
if (!useNode20InUnsupportedSystem && (useNode24InUnsupportedSystem || container.NeedsNode20Redirect))
11191173
{
11201174
var node20 = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), NodeHandler.Node20_1Folder, "bin", $"node{IOUtil.ExeExtension}"));
11211175

@@ -1130,12 +1184,24 @@ string useDoubleQuotes(string value)
11301184
executionContext,
11311185
new Dictionary<string, string>
11321186
{
1133-
{ "ContainerNode20to16Fallback", container.NeedsNode16Redirect.ToString() }
1187+
{ "ContainerNode20to16Fallback", container.NeedsNode16Redirect.ToString() }
11341188
}
11351189
);
11361190
}
11371191
}
11381192

1193+
if (!container.NeedsNode20Redirect)
1194+
{
1195+
container.ResultNodePath = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), NodeHandler.Node24Folder, "bin", $"node{IOUtil.ExeExtension}"));
1196+
}
1197+
else if (!container.NeedsNode16Redirect)
1198+
{
1199+
container.ResultNodePath = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), NodeHandler.Node20_1Folder, "bin", $"node{IOUtil.ExeExtension}"));
1200+
}
1201+
else
1202+
{
1203+
container.ResultNodePath = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), NodeHandler.Node16Folder, "bin", $"node{IOUtil.ExeExtension}"));
1204+
}
11391205
}
11401206

11411207
if (!string.IsNullOrEmpty(containerUserName))

0 commit comments

Comments
 (0)