Skip to content

Commit

Permalink
Add ability to grab the FRAMEWORK_VERSION for function apps (Azure-Ap…
Browse files Browse the repository at this point in the history
  • Loading branch information
ankitkumarr authored and sanchitmehta committed Sep 26, 2019
1 parent 9290273 commit 68ddf24
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 19 deletions.
5 changes: 5 additions & 0 deletions Kudu.Core/Deployment/Generator/SiteBuilderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public ISiteBuilder CreateBuilder(ITracer tracer, ILogger logger, IDeploymentSet
return new BasicBuilder(_environment, settings, _propertyProvider, repositoryRoot, projectPath);
}

// If ENABLE_ORYX_BUILD is not set, for function app, we assume it on by default
string enableOryxBuild = System.Environment.GetEnvironmentVariable("ENABLE_ORYX_BUILD");
if (!string.IsNullOrEmpty(enableOryxBuild))
{
Expand All @@ -72,6 +73,10 @@ public ISiteBuilder CreateBuilder(ITracer tracer, ILogger logger, IDeploymentSet
return new OryxBuilder(_environment, settings, _propertyProvider, repositoryRoot);
}
}
else if (FunctionAppHelper.LooksLikeFunctionApp())
{
return new OryxBuilder(_environment, settings, _propertyProvider, repositoryRoot);
}

if (!String.IsNullOrEmpty(targetProjectPath))
{
Expand Down
6 changes: 3 additions & 3 deletions Kudu.Core/Deployment/Oryx/BuildFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ public enum BuildOptimizationsFlags

public class BuildFlagsHelper
{
public static BuildOptimizationsFlags Parse(string value)
public static BuildOptimizationsFlags Parse(string value, BuildOptimizationsFlags defaultVal = BuildOptimizationsFlags.None)
{
if (string.IsNullOrEmpty(value))
{
return BuildOptimizationsFlags.None;
return defaultVal;
}

try
Expand All @@ -29,7 +29,7 @@ public static BuildOptimizationsFlags Parse(string value)
}
catch (Exception)
{
return BuildOptimizationsFlags.None;
return defaultVal;
}
}
}
Expand Down
60 changes: 55 additions & 5 deletions Kudu.Core/Deployment/Oryx/FunctionAppOryxArguments.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Kudu.Core.Infrastructure;
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace Kudu.Core.Deployment.Oryx
{
Expand All @@ -19,7 +21,7 @@ public FunctionAppOryxArguments()
FunctionsWorkerRuntime = ResolveWorkerRuntime();
RunOryxBuild = FunctionsWorkerRuntime != WorkerRuntime.None;
var buildFlags = GetEnvironmentVariableOrNull(OryxBuildConstants.OryxEnvVars.BuildFlagsSetting);
Flags = BuildFlagsHelper.Parse(buildFlags);
Flags = BuildFlagsHelper.Parse(buildFlags, defaultVal: BuildOptimizationsFlags.UseExpressBuild);
SkipKuduSync = Flags == BuildOptimizationsFlags.UseExpressBuild;
}

Expand Down Expand Up @@ -70,10 +72,6 @@ protected void AddLanguage(StringBuilder args, WorkerRuntime workerRuntime)
case WorkerRuntime.Python:
OryxArgumentsHelper.AddLanguage(args, "python");
break;

case WorkerRuntime.PHP:
OryxArgumentsHelper.AddLanguage(args, "php");
break;
}
}

Expand Down Expand Up @@ -121,9 +119,61 @@ private WorkerRuntime ResolveWorkerRuntime()

private string ResolveWorkerRuntimeVersion(WorkerRuntime workerRuntime)
{
var framework = GetEnvironmentVariableOrNull(OryxBuildConstants.OryxEnvVars.FrameworkSetting);
var frameworkVersion = GetEnvironmentVariableOrNull(OryxBuildConstants.OryxEnvVars.FrameworkVersionSetting);

// If either of them is not set we are not in a position to determine the version, and should let the caller
// switch to default
if (string.IsNullOrEmpty(framework) || string.IsNullOrEmpty(frameworkVersion))
{
return FunctionAppSupportedWorkerRuntime.GetDefaultLanguageVersion(workerRuntime);
}

// If it's set to DOCKER, it could be a) a function app image b) a custom image
// For custom image, there's no point doing a build, so we just default them (the parser won't work).
// if it's indeed a function app image, we look for the right tag that tells us about the version.
//
// Or if it's set to a supported worker runtime that was inferred, we assume that the framework version
// that is set is the correct version requested.
if (framework.Equals("DOCKER", StringComparison.OrdinalIgnoreCase))
{
var parsedVersion = ParseRuntimeVersionFromImage(frameworkVersion);
if (!string.IsNullOrEmpty(parsedVersion))
{
return parsedVersion;
}
}
else if (framework.Equals(workerRuntime.ToString(), StringComparison.OrdinalIgnoreCase))
{
return frameworkVersion;
}

return FunctionAppSupportedWorkerRuntime.GetDefaultLanguageVersion(workerRuntime);
}

public static string ParseRuntimeVersionFromImage(string imageName)
{
// The image name would be in this format -- 'mcr.microsoft.com/azure-functions/python:2.0-python3.6-appservice'
// If we get any parsing issues, we return null here.
try
{
var imageTag = imageName.Substring(imageName.LastIndexOf(':') + 1);
var versionRegex = new Regex(@"^[0-9]+\.[0-9]+\-[A-Za-z]+([0-9].*)\-appservice$");
var versionMatch = versionRegex.Match(imageTag);
var version = versionMatch?.Groups[1]?.Value;
if (!string.IsNullOrEmpty(version))
{
return version;
}
return null;
}
catch (Exception)
{
// TODO: Log at ETW event later
return null;
}
}

private string GetEnvironmentVariableOrNull(string environmentVarName)
{
var environmentVarValue = System.Environment.GetEnvironmentVariable(environmentVarName);
Expand Down
10 changes: 1 addition & 9 deletions Kudu.Core/Deployment/Oryx/FunctionAppSupportedWorkerRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ public enum WorkerRuntime
None,
Node,
Python,
DotNet,
PHP
DotNet
}

public class FunctionAppSupportedWorkerRuntime
Expand All @@ -31,10 +30,6 @@ public static WorkerRuntime ParseWorkerRuntime(string value)
{
return WorkerRuntime.DotNet;
}
else if (value.StartsWith("PHP", StringComparison.OrdinalIgnoreCase))
{
return WorkerRuntime.PHP;
}

return WorkerRuntime.None;
}
Expand All @@ -52,9 +47,6 @@ public static string GetDefaultLanguageVersion(WorkerRuntime workerRuntime)
case WorkerRuntime.Python:
return OryxBuildConstants.FunctionAppWorkerRuntimeDefaults.Python;

case WorkerRuntime.PHP:
return OryxBuildConstants.FunctionAppWorkerRuntimeDefaults.PHP;

default:
return "";
}
Expand Down
4 changes: 2 additions & 2 deletions Kudu.Core/Deployment/Oryx/OryxBuildConstants.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System.Collections.Generic;
using System.IO;

namespace Kudu.Core.Deployment.Oryx
{
Expand All @@ -23,7 +24,6 @@ internal static class FunctionAppWorkerRuntimeDefaults
public static readonly string Node = "8.15";
public static readonly string Python = "3.6";
public static readonly string Dotnet = "2.2";
public static readonly string PHP = "7.3";
}

internal static class FunctionAppBuildSettings
Expand Down
13 changes: 13 additions & 0 deletions Kudu.Tests/Core/Deployment/Oryx/OryxArgumentsFunctionAppTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,18 @@ public void SkipKuduSyncOnExpressBuildTest()
command);
}
}

[Theory]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-python3.7-appservice", "3.7")]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-python3.6-appservice", "3.6")]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-node8-appservice", "8")]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-node10-appservice", "10")]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-dotnet-appservice", null)]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-dotnet2.0-appservice", "2.0")]
[InlineData("mcr.microsoft.com/azure-functions/python:2.0-dotnet3.0-appservice", "3.0")]
public void TestVersionFromImage(string imageName, string version)
{
Assert.Equal(version, FunctionAppOryxArguments.ParseRuntimeVersionFromImage(imageName));
}
}
}

0 comments on commit 68ddf24

Please sign in to comment.