diff --git a/src/Agent.Sdk/Knob/AgentKnobs.cs b/src/Agent.Sdk/Knob/AgentKnobs.cs index 27f57912b6..f08b0ffce1 100644 --- a/src/Agent.Sdk/Knob/AgentKnobs.cs +++ b/src/Agent.Sdk/Knob/AgentKnobs.cs @@ -230,6 +230,13 @@ public class AgentKnobs new RuntimeKnobSource("ALLOW_TFVC_UNSHELVE_ERRORS"), new EnvironmentKnobSource("ALLOW_TFVC_UNSHELVE_ERRORS"), new BuiltInDefaultKnobSource("false")); - } + // Set DISABLE_JAVA_CAPABILITY_HIGHER_THAN_9 variable with any value + // to disable recognition of Java higher than 9 + public static readonly Knob DisableRecognitionOfJDKHigherThen9 = new Knob( + nameof(DisableRecognitionOfJDKHigherThen9), + "Recognize JDK and JRE >= 9 installed on the machine as agent capability. Setting any value to DISABLE_JAVA_CAPABILITY_HIGHER_THAN_9 is disabling this behavior", + new EnvironmentKnobSource("DISABLE_JAVA_CAPABILITY_HIGHER_THAN_9"), + new BuiltInDefaultKnobSource(string.Empty)); + } } diff --git a/src/Misc/layoutbin/powershell/Add-JavaCapabilities.ps1 b/src/Misc/layoutbin/powershell/Add-JavaCapabilities.ps1 index adbbb1d386..06e68bb8a8 100644 --- a/src/Misc/layoutbin/powershell/Add-JavaCapabilities.ps1 +++ b/src/Misc/layoutbin/powershell/Add-JavaCapabilities.ps1 @@ -9,6 +9,13 @@ $jdk6KeyName = "Software\JavaSoft\Java Development Kit\1.6" $jdk7KeyName = "Software\JavaSoft\Java Development Kit\1.7" $jdk8KeyName = "Software\JavaSoft\Java Development Kit\1.8" +# JRE/JDK keys for major version >= 9 +$jdk9AndGreaterNameOracle = "Software\JavaSoft\JDK" +$jre9AndGreaterNameOracle = "Software\JavaSoft\JRE" +$jre9AndGreaterName = "Software\JavaSoft\Java Runtime Environment" +$jdk9AndGreaterName = "Software\JavaSoft\Java Development Kit" +$minimumMajorVersion9 = 9 + # Check for JRE. $latestJre = $null $null = Add-CapabilityFromRegistry -Name 'java_6' -Hive 'LocalMachine' -View 'Registry32' -KeyName $jre6KeyName -ValueName 'JavaHome' -Value ([ref]$latestJre) @@ -17,6 +24,19 @@ $null = Add-CapabilityFromRegistry -Name 'java_8' -Hive 'LocalMachine' -View 'Re $null = Add-CapabilityFromRegistry -Name 'java_6_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jre6KeyName -ValueName 'JavaHome' -Value ([ref]$latestJre) $null = Add-CapabilityFromRegistry -Name 'java_7_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jre7KeyName -ValueName 'JavaHome' -Value ([ref]$latestJre) $null = Add-CapabilityFromRegistry -Name 'java_8_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jre8KeyName -ValueName 'JavaHome' -Value ([ref]$latestJre) + +if (-not (Test-Path env:DISABLE_JAVA_CAPABILITY_HIGHER_THAN_9)) { + try { + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'java_' -Hive 'LocalMachine' -View 'Registry32' -KeyName $jre9AndGreaterName -ValueName 'JavaHome' -Value ([ref]$latestJre) -MinimumMajorVersion $minimumMajorVersion9 + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'java_' -Hive 'LocalMachine' -View 'Registry32' -KeyName $jre9AndGreaterNameOracle -ValueName 'JavaHome' -Value ([ref]$latestJre) -MinimumMajorVersion $minimumMajorVersion9 + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'java_' -PostfixName '_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jre9AndGreaterName -ValueName 'JavaHome' -Value ([ref]$latestJre) -MinimumMajorVersion $minimumMajorVersion9 + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'java_' -PostfixName '_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jre9AndGreaterNameOracle -ValueName 'JavaHome' -Value ([ref]$latestJre) -MinimumMajorVersion $minimumMajorVersion9 + } catch { + Write-Host "An error occured while trying to check if there are JRE >= 9" + Write-Host $_ + } +} + if ($latestJre) { # Favor x64. Write-Capability -Name 'java' -Value $latestJre @@ -30,6 +50,19 @@ $null = Add-CapabilityFromRegistry -Name 'jdk_8' -Hive 'LocalMachine' -View 'Reg $null = Add-CapabilityFromRegistry -Name 'jdk_6_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jdk6KeyName -ValueName 'JavaHome' -Value ([ref]$latestJdk) $null = Add-CapabilityFromRegistry -Name 'jdk_7_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jdk7KeyName -ValueName 'JavaHome' -Value ([ref]$latestJdk) $null = Add-CapabilityFromRegistry -Name 'jdk_8_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jdk8KeyName -ValueName 'JavaHome' -Value ([ref]$latestJdk) + +if (-not (Test-Path env:DISABLE_JAVA_CAPABILITY_HIGHER_THAN_9)) { + try { + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'jdk_' -Hive 'LocalMachine' -View 'Registry32' -KeyName $jdk9AndGreaterName -ValueName 'JavaHome' -Value ([ref]$latestJdk) -MinimumMajorVersion $minimumMajorVersion9 + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'jdk_' -Hive 'LocalMachine' -View 'Registry32' -KeyName $jdk9AndGreaterNameOracle -ValueName 'JavaHome' -Value ([ref]$latestJdk) -MinimumMajorVersion $minimumMajorVersion9 + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'jdk_' -PostfixName '_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jdk9AndGreaterName -ValueName 'JavaHome' -Value ([ref]$latestJdk) -MinimumMajorVersion $minimumMajorVersion9 + $null = Add-CapabilityFromRegistryWithLastVersionAvailable -PrefixName 'jdk_' -PostfixName '_x64' -Hive 'LocalMachine' -View 'Registry64' -KeyName $jdk9AndGreaterNameOracle -ValueName 'JavaHome' -Value ([ref]$latestJdk) -MinimumMajorVersion $minimumMajorVersion9 + } catch { + Write-Host "An error occured while trying to check if there are JDK >= 9" + Write-Host $_ + } +} + if ($latestJdk) { # Favor x64. Write-Capability -Name 'jdk' -Value $latestJdk diff --git a/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityFunctions.ps1 b/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityFunctions.ps1 index ac301bca47..d436aa1e04 100644 --- a/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityFunctions.ps1 +++ b/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityFunctions.ps1 @@ -83,6 +83,146 @@ function Add-CapabilityFromRegistry { return $true } + +function Add-CapabilityFromRegistryWithLastVersionAvailableForSubkey { + <# + .SYNOPSIS + Retrieves capability from registry for specified key and subkey. Considers that subkey has semver format + #> + [CmdletBinding()] + param( + # Prefix name of capability + [Parameter(Mandatory = $true)] + [string]$PrefixName, + # Postfix name of capability + [Parameter(Mandatory = $false)] + [string]$PostfixName, + + [Parameter(Mandatory = $true)] + [ValidateSet('CurrentUser', 'LocalMachine')] + [string]$Hive, + + [Parameter(Mandatory = $true)] + [ValidateSet('Default', 'Registry32', 'Registry64')] + [string]$View, + # Registry key + [Parameter(Mandatory = $true)] + [string]$KeyName, + + [Parameter(Mandatory = $true)] + [string]$ValueName, + # Registry subkey + [Parameter(Mandatory = $true)] + [string]$Subkey, + # Major version of tool to be added as capability + [Parameter(Mandatory = $true)] + [int]$MajorVersion, + # Minimum major version of tool to be added as capability. All versions detected less than this version - will be ignored. + # This is helpful for backward compatibility with already existing logic for previous versions + [Parameter(Mandatory = $false)] + [int]$MinimumMajorVersion, + + [ref]$Value) + try { + Write-Host $MajorVersion $MinimumMajorVersion + if ($MajorVersion -lt $MinimumMajorVersion) { + return $false + } + + $wholeKey = Join-Path -Path $KeyName -ChildPath $Subkey + + $capabilityValue = Get-RegistryValue -Hive $Hive -View $View -KeyName $wholeKey -ValueName $ValueName + + if ([string]::IsNullOrEmpty($capabilityValue)) { + return $false + } + + $capabilityName = $PrefixName + $MajorVersion + $PostfixName + + Write-Capability -Name $capabilityName -Value $capabilityValue + if ($Value) { + $Value.Value = $capabilityValue + } + + return $true + } catch { + return $false + } +} + +function Add-CapabilityFromRegistryWithLastVersionAvailable { + <# + .SYNOPSIS + Retrieves capability from registry with last version. Considers that subkeys for specified key name are versions (in semver format like 1.2.3) + This is useful to detect last version of tools as agent capabilities + + .EXAMPLE + If KeyName = 'SOFTWARE\JavaSoft\JDK', and this registry key contains subkeys: 14.0.1, 16.0 - it will write the last one as specified capability + #> + [CmdletBinding()] + param( + # Prefix name of capability + [Parameter(Mandatory = $true)] + [string]$PrefixName, + # Postfix name of capability + [Parameter(Mandatory = $false)] + [string]$PostfixName, + + [Parameter(Mandatory = $true)] + [ValidateSet('CurrentUser', 'LocalMachine')] + [string]$Hive, + + [Parameter(Mandatory = $true)] + [ValidateSet('Default', 'Registry32', 'Registry64')] + [string]$View, + # Registry key + [Parameter(Mandatory = $true)] + [string]$KeyName, + + [Parameter(Mandatory = $true)] + [string]$ValueName, + # Minimum major version of tool to be added as capability. All versions detected less than this version - will be ignored. + # This is helpful for backward compatibility with already existing logic for previous versions + [Parameter(Mandatory = $false)] + [string]$MinimumMajorVersion, + + [ref]$Value) + + try { + $subkeys = Get-RegistrySubKeyNames -Hive $Hive -View $View -KeyName $KeyName | Sort-Object + + $versionSubkeys = $subkeys | ForEach {[tuple]::Create((Parse-Version -Version $_), $_)} | Where { ![string]::IsNullOrEmpty($_.Item1)} + + $sortedVersionSubkeys = $versionSubkeys | Sort-Object -Property @{Expression = {$_.Item1}; Descending = $False} + Write-Host $sortedVersionSubkeys[-1].Item1.Major + $res = Add-CapabilityFromRegistryWithLastVersionAvailableForSubkey -PrefixName $PrefixName -PostfixName $PostfixName -Hive $Hive -View $View -KeyName $KeyName -ValueName $ValueName -Subkey $sortedVersionSubkeys[-1].Item2 -MajorVersion $sortedVersionSubkeys[-1].Item1.Major -Value $Value -MinimumMajorVersion $MinimumMajorVersion + + if (!$res) { + Write-Host "An error occured while trying to get last available version for capability: " $PrefixName + "" + $PostfixName + Write-Host $_ + + $major = (Parse-Version -Version $subkeys[-1]).Major + + $res = Add-CapabilityFromRegistryWithLastVersionAvailableForSubkey -PrefixName $PrefixName -PostfixName $PostfixName -Hive $Hive -View $View -KeyName $KeyName -ValueName $ValueName -Subkey $subkeys[-1] -MajorVersion $major -Value $Value -MinimumMajorVersion $MinimumMajorVersion + + if(!$res) { + Write-Host "An error occured while trying to set capability for first found subkey: " $subkeys[-1] + Write-Host $_ + + return $false + } + } + + return $true + } catch { + Write-Host "An error occured while trying to sort subkeys for capability as versions: " $PrefixName + "" + $PostfixName + Write-Host $_ + + return $false + } +} + + function Write-Capability { [CmdletBinding()] param( diff --git a/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityHelpers.psm1 b/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityHelpers.psm1 index d960beff82..97d2e3a8df 100644 --- a/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityHelpers.psm1 +++ b/src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityHelpers.psm1 @@ -8,6 +8,7 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\PathFunctions . $PSScriptRoot\RegistryFunctions . $PSScriptRoot\VisualStudioFunctions +. $PSScriptRoot\VersionFunctions # Export the public functions. Export-ModuleMember -Function @( @@ -15,6 +16,7 @@ Export-ModuleMember -Function @( 'Add-CapabilityFromApplication' 'Add-CapabilityFromEnvironment' 'Add-CapabilityFromRegistry' + 'Add-CapabilityFromRegistryWithLastVersionAvailable' 'Write-Capability' # File system functions with tracing built-in. 'Test-Container' diff --git a/src/Misc/layoutbin/powershell/CapabilityHelpers/RegistryFunctions.ps1 b/src/Misc/layoutbin/powershell/CapabilityHelpers/RegistryFunctions.ps1 index ad2032e3fc..f74adf7b14 100644 --- a/src/Misc/layoutbin/powershell/CapabilityHelpers/RegistryFunctions.ps1 +++ b/src/Misc/layoutbin/powershell/CapabilityHelpers/RegistryFunctions.ps1 @@ -172,4 +172,4 @@ function Get-RegistryValueNames { $null = $baseKey.Dispose() } } -} +} \ No newline at end of file diff --git a/src/Misc/layoutbin/powershell/CapabilityHelpers/VersionFunctions.ps1 b/src/Misc/layoutbin/powershell/CapabilityHelpers/VersionFunctions.ps1 new file mode 100644 index 0000000000..c95575a92a --- /dev/null +++ b/src/Misc/layoutbin/powershell/CapabilityHelpers/VersionFunctions.ps1 @@ -0,0 +1,25 @@ +function Parse-Version { + <# + .SYNOPSIS + Parses version from provided. Allows incomplete versions like 16.0. Returns empty string if there is more than 4 numbers divided by dot or string is not in semver format + + .EXAMPLE + Parse-Version -Version "1.3.5" + + #> + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$Version) + + if ($Version.IndexOf(".") -lt 0) { + return [System.Version]::Parse("$($Version).0") + } + try { + $res = [System.Version]::Parse($Version) + + return $res + } catch { + return "" + } +} \ No newline at end of file