Skip to content

Commit 3bc9f75

Browse files
committed
Fixed an ElasticBeanstalk deployment issue for Linux platform where Procfile was sometimes being generated with incorrect entrypoint when multiple runtimeconfig.json files were present.
1 parent 642bfa2 commit 3bc9f75

File tree

2 files changed

+75
-7
lines changed

2 files changed

+75
-7
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"Projects": [
3+
{
4+
"Name": "Amazon.ElasticBeanstalk.Tools",
5+
"Type": "Patch",
6+
"ChangelogMessages": [
7+
"Fixed an ElasticBeanstalk deployment issue for Linux platform where Procfile was sometimes being generated with incorrect entrypoint when multiple runtimeconfig.json files were present."
8+
]
9+
}
10+
]
11+
}

src/Amazon.ElasticBeanstalk.Tools/EBUtilities.cs

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Globalization;
44
using System.IO;
55
using System.Linq;
6-
using System.Runtime.CompilerServices;
76
using Amazon.Common.DotNetCli.Tools;
87
using Amazon.ElasticBeanstalk.Model;
98
using Amazon.ElasticBeanstalk.Tools.Commands;
@@ -108,26 +107,24 @@ public static bool IsLoadBalancedEnvironmentType(string environmentType)
108107
return string.Equals(environmentType, EBConstants.ENVIRONMENT_TYPE_LOADBALANCED, StringComparison.OrdinalIgnoreCase);
109108
}
110109

111-
112110
public static void SetupPackageForLinux(IToolLogger logger, EBBaseCommand command, DeployEnvironmentProperties options, string publishLocation, string reverseProxy, int? applicationPort)
113111
{
114112
// Setup Procfile
115113
var procfilePath = Path.Combine(publishLocation, "Procfile");
116114

117-
if(File.Exists(procfilePath))
115+
if (File.Exists(procfilePath))
118116
{
119117
logger?.WriteLine("Found existing Procfile file found and using that for deployment");
120118
return;
121119
}
122120

123121
logger?.WriteLine("Writing Procfile for deployment bundle");
124-
125-
var runtimeConfigFilePath = Directory.GetFiles(publishLocation, "*.runtimeconfig.json").FirstOrDefault();
122+
string runtimeConfigFilePath = GetRuntimeConfigFilePath(publishLocation);
126123
var runtimeConfigFileName = Path.GetFileName(runtimeConfigFilePath);
127124
var executingAssembly = runtimeConfigFileName.Substring(0, runtimeConfigFileName.Length - "runtimeconfig.json".Length - 1);
128125

129126
string webCommandLine;
130-
if(IsSelfContainedPublish(runtimeConfigFilePath))
127+
if (IsSelfContainedPublish(runtimeConfigFilePath))
131128
{
132129
webCommandLine = $"./{executingAssembly}";
133130
}
@@ -136,7 +133,7 @@ public static void SetupPackageForLinux(IToolLogger logger, EBBaseCommand comman
136133
webCommandLine = $"dotnet exec ./{executingAssembly}.dll";
137134
}
138135

139-
if(string.Equals(reverseProxy, EBConstants.PROXY_SERVER_NONE, StringComparison.InvariantCulture))
136+
if (string.Equals(reverseProxy, EBConstants.PROXY_SERVER_NONE, StringComparison.InvariantCulture))
140137
{
141138
logger?.WriteLine("... Proxy server disabled, configuring Kestrel to listen to traffic from all hosts");
142139
var port = applicationPort.HasValue ? applicationPort.Value : EBConstants.DEFAULT_APPLICATION_PORT;
@@ -175,5 +172,65 @@ public static string FindExistingValue(this List<ConfigurationOptionSetting> set
175172
var setting = settings?.FirstOrDefault(x => string.Equals(x.Namespace, ns, StringComparison.InvariantCulture) && string.Equals(x.OptionName, name, StringComparison.InvariantCulture));
176173
return setting?.Value;
177174
}
175+
176+
private static string GetRuntimeConfigFilePath(string publishLocation)
177+
{
178+
var runtimeConfigFiles = Directory.GetFiles(publishLocation, "*.runtimeconfig.json");
179+
180+
// Handle case where application could have multiple runtimeconfig.json files in publish location.
181+
if (runtimeConfigFiles.Length > 1)
182+
{
183+
foreach (var file in runtimeConfigFiles)
184+
{
185+
var fileContent = File.ReadAllText(file);
186+
187+
JsonData root = JsonMapper.ToObject(fileContent);
188+
JsonData runtimeOptions = root["runtimeOptions"] as JsonData;
189+
if (runtimeOptions == null)
190+
{
191+
continue;
192+
}
193+
194+
// runtimeOptions node can contain framework or frameworks (refer https://github.com/dotnet/sdk/blob/main/documentation/specs/runtime-configuration-file.md#runtimeoptions-section-runtimeconfigjson).
195+
var frameworkNode = runtimeOptions["framework"];
196+
var frameworksNode = runtimeOptions["frameworks"];
197+
198+
if (IsAspNetFramework(frameworkNode))
199+
{
200+
return file;
201+
}
202+
203+
if (frameworksNode != null && frameworksNode.Count > 0)
204+
{
205+
foreach (var framework in frameworksNode)
206+
{
207+
var tempNode = framework as JsonData;
208+
if (IsAspNetFramework(tempNode))
209+
{
210+
return file;
211+
}
212+
}
213+
}
214+
}
215+
}
216+
217+
return Directory.GetFiles(publishLocation, "*.runtimeconfig.json").FirstOrDefault();
218+
}
219+
220+
private static bool IsAspNetFramework(JsonData frameworkNode)
221+
{
222+
if (frameworkNode != null)
223+
{
224+
var name = frameworkNode["name"];
225+
226+
if (name != null)
227+
{
228+
string frameworkName = (string)name;
229+
return !string.IsNullOrEmpty(frameworkName) && frameworkName.StartsWith("Microsoft.AspNetCore");
230+
}
231+
}
232+
233+
return false;
234+
}
178235
}
179236
}

0 commit comments

Comments
 (0)