1010using System . Net . Http ;
1111using System . Resources ;
1212using System . Threading . Tasks ;
13+ using Microsoft . Azure . WebJobs . Script . Config ;
1314using Microsoft . Azure . WebJobs . Script . Configuration ;
1415using Microsoft . Azure . WebJobs . Script . Diagnostics . Extensions ;
1516using Microsoft . Azure . WebJobs . Script . Models ;
@@ -23,16 +24,18 @@ public class ExtensionBundleManager : IExtensionBundleManager
2324 {
2425 private readonly IEnvironment _environment ;
2526 private readonly ExtensionBundleOptions _options ;
27+ private readonly FunctionsHostingConfigOptions _configOption ;
2628 private readonly ILogger _logger ;
2729 private readonly string _cdnUri ;
2830 private string _extensionBundleVersion ;
2931
30- public ExtensionBundleManager ( ExtensionBundleOptions options , IEnvironment environment , ILoggerFactory loggerFactory )
32+ public ExtensionBundleManager ( ExtensionBundleOptions options , IEnvironment environment , ILoggerFactory loggerFactory , FunctionsHostingConfigOptions configOption )
3133 {
3234 _environment = environment ?? throw new ArgumentNullException ( nameof ( environment ) ) ;
3335 _logger = loggerFactory . CreateLogger < ExtensionBundleManager > ( ) ?? throw new ArgumentNullException ( nameof ( loggerFactory ) ) ;
3436 _cdnUri = _environment . GetEnvironmentVariable ( EnvironmentSettingNames . ExtensionBundleSourceUri ) ?? ScriptConstants . ExtensionBundleDefaultSourceUri ;
3537 _options = options ?? throw new ArgumentNullException ( nameof ( options ) ) ;
38+ _configOption = configOption ?? throw new ArgumentNullException ( nameof ( configOption ) ) ;
3639 }
3740
3841 public async Task < ExtensionBundleDetails > GetExtensionBundleDetails ( )
@@ -128,7 +131,7 @@ internal bool TryLocateExtensionBundle(out string bundlePath)
128131 if ( FileUtility . DirectoryExists ( path ) )
129132 {
130133 var bundleDirectories = FileUtility . EnumerateDirectories ( path ) ;
131- string version = FindBestVersionMatch ( _options . Version , bundleDirectories ) ;
134+ string version = FindBestVersionMatch ( _options . Version , bundleDirectories , _options . Id , _configOption ) ;
132135
133136 if ( ! string . IsNullOrEmpty ( version ) )
134137 {
@@ -236,7 +239,8 @@ private async Task<string> GetLatestMatchingBundleVersionAsync(HttpClient httpCl
236239
237240 var content = await response . Content . ReadAsStringAsync ( ) ;
238241 var bundleVersions = JsonConvert . DeserializeObject < IEnumerable < string > > ( content ) ;
239- var matchingBundleVersion = FindBestVersionMatch ( _options . Version , bundleVersions ) ;
242+
243+ var matchingBundleVersion = FindBestVersionMatch ( _options . Version , bundleVersions , _options . Id , _configOption ) ;
240244
241245 if ( string . IsNullOrEmpty ( matchingBundleVersion ) )
242246 {
@@ -246,7 +250,7 @@ private async Task<string> GetLatestMatchingBundleVersionAsync(HttpClient httpCl
246250 return matchingBundleVersion ;
247251 }
248252
249- private static string FindBestVersionMatch ( VersionRange versionRange , IEnumerable < string > versions )
253+ internal static string FindBestVersionMatch ( VersionRange versionRange , IEnumerable < string > versions , string bundleId , FunctionsHostingConfigOptions configOption )
250254 {
251255 var bundleVersions = versions . Select ( p =>
252256 {
@@ -259,7 +263,34 @@ private static string FindBestVersionMatch(VersionRange versionRange, IEnumerabl
259263 return version ;
260264 } ) . Where ( v => v != null ) ;
261265
262- return bundleVersions . OrderByDescending ( version => version . Version ) . FirstOrDefault ( ) ? . ToString ( ) ;
266+ var matchingVersion = bundleVersions . OrderByDescending ( version => version . Version ) . FirstOrDefault ( ) ;
267+
268+ if ( bundleId != ScriptConstants . DefaultExtensionBundleId )
269+ {
270+ return matchingVersion ? . ToString ( ) ;
271+ }
272+
273+ // Check to see if there is a max bundle version set via hosting configuration, if yes then use that instead of the one
274+ // available on VM or local machine. Only use MaximumBundleV3Version or MaximumBundleV4Version if the version configured
275+ // by the customer resolved to version higher than the version set via hosting config.
276+ if ( ! string . IsNullOrEmpty ( configOption . MaximumBundleV3Version )
277+ && matchingVersion ? . Major == ScriptConstants . ExtensionBundleV3MajorVersion )
278+ {
279+ var maximumBundleV3Version = NuGetVersion . Parse ( configOption . MaximumBundleV3Version ) ;
280+ matchingVersion = matchingVersion > maximumBundleV3Version ? maximumBundleV3Version : matchingVersion ;
281+ return matchingVersion ? . ToString ( ) ;
282+ }
283+
284+ if ( ! string . IsNullOrEmpty ( configOption . MaximumBundleV4Version )
285+ && matchingVersion ? . Major == ScriptConstants . ExtensionBundleV4MajorVersion )
286+ {
287+ var maximumBundleV4Version = NuGetVersion . Parse ( configOption . MaximumBundleV4Version ) ;
288+ matchingVersion = matchingVersion > maximumBundleV4Version
289+ ? maximumBundleV4Version
290+ : matchingVersion ;
291+ }
292+
293+ return matchingVersion ? . ToString ( ) ;
263294 }
264295
265296 public async Task < string > GetExtensionBundleBinPathAsync ( )
0 commit comments