Skip to content

Commit 387264b

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 387264b

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
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: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.CompilerServices;
77
using Amazon.Common.DotNetCli.Tools;
88
using Amazon.ElasticBeanstalk.Model;
9+
using Amazon.ElasticBeanstalk.Model.Internal.MarshallTransformations;
910
using Amazon.ElasticBeanstalk.Tools.Commands;
1011
using ThirdParty.Json.LitJson;
1112

@@ -108,26 +109,24 @@ public static bool IsLoadBalancedEnvironmentType(string environmentType)
108109
return string.Equals(environmentType, EBConstants.ENVIRONMENT_TYPE_LOADBALANCED, StringComparison.OrdinalIgnoreCase);
109110
}
110111

111-
112112
public static void SetupPackageForLinux(IToolLogger logger, EBBaseCommand command, DeployEnvironmentProperties options, string publishLocation, string reverseProxy, int? applicationPort)
113113
{
114114
// Setup Procfile
115115
var procfilePath = Path.Combine(publishLocation, "Procfile");
116116

117-
if(File.Exists(procfilePath))
117+
if (File.Exists(procfilePath))
118118
{
119119
logger?.WriteLine("Found existing Procfile file found and using that for deployment");
120120
return;
121121
}
122122

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

129128
string webCommandLine;
130-
if(IsSelfContainedPublish(runtimeConfigFilePath))
129+
if (IsSelfContainedPublish(runtimeConfigFilePath))
131130
{
132131
webCommandLine = $"./{executingAssembly}";
133132
}
@@ -136,7 +135,7 @@ public static void SetupPackageForLinux(IToolLogger logger, EBBaseCommand comman
136135
webCommandLine = $"dotnet exec ./{executingAssembly}.dll";
137136
}
138137

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

0 commit comments

Comments
 (0)