SharedResources/Src/InstallHpcNode/xHpcPack/DSCResources/MSFT_xHpcHeadNodeInstall/MSFT_xHpcHeadNodeInstall.psm1 (273 lines of code) (raw):
#
# xHpcPackInstall: DSC resource to install HPC Pack 2019 head node.
#
function Get-TargetResource
{
[OutputType([System.Collections.Hashtable])]
param
(
[parameter(Mandatory = $true)]
[string] $ClusterName,
[parameter(Mandatory = $true)]
[string] $SetupPkgPath,
[parameter(Mandatory = $true)]
[string] $SSLThumbprint,
[parameter(Mandatory = $false)]
[string] $HeadNodeList = "",
[parameter(Mandatory = $false)]
[string] $SQLServerInstance = "",
[parameter(Mandatory = $false)]
[System.Management.Automation.PSCredential] $SQLCredential,
[parameter(Mandatory = $false)]
[Boolean] $LinuxCommOverHttp = $false,
[parameter(Mandatory = $false)]
[string] $LinuxAuthenticationKey = "",
[Parameter(Mandatory=$false)]
[Boolean] $EnableBuiltinHA = $false
)
return $PSBoundParameters
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[string] $ClusterName,
[parameter(Mandatory = $true)]
[string] $SetupPkgPath,
[parameter(Mandatory = $true)]
[string] $SSLThumbprint,
[parameter(Mandatory = $false)]
[string] $HeadNodeList = "",
[parameter(Mandatory = $false)]
[string] $SQLServerInstance = "",
[parameter(Mandatory = $false)]
[System.Management.Automation.PSCredential] $SQLCredential,
[parameter(Mandatory = $false)]
[Boolean] $LinuxCommOverHttp = $false,
[parameter(Mandatory = $false)]
[string] $LinuxAuthenticationKey = "",
[Parameter(Mandatory=$false)]
[Boolean] $EnableBuiltinHA = $false
)
$downloader = New-Object System.Net.WebClient
# Download the setup package if it is an http/https url
if($SetupPkgPath -match "^https?://")
{
$setupPkgUrl = $SetupPkgPath
$SetupPkgPath = Join-Path "$env:windir\Temp" $($setupPkgUrl -split '/')[-1]
DownloadFile -Downloader $downloader -SourceUrl $setupPkgUrl -DestPath $SetupPkgPath
}
if((Test-Path -Path $SetupPkgPath -PathType Leaf) -and [IO.Path]::GetExtension($SetupPkgPath) -eq ".zip")
{
$basetgtdir = $SetupPkgPath.Substring(0, $SetupPkgPath.LastIndexOf('.')) + '_HPC'
$tgtdir = $basetgtdir
$index = 0
while(Test-Path -Path $tgtdir -PathType Container)
{
try
{
Remove-Item -Path $tgtdir -Recurse -Force -ErrorAction Stop
break
}
catch
{
$tgtdir = "$basetgtdir" + "_$index"
}
}
[System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null
[System.IO.Compression.ZipFile]::ExtractToDirectory($SetupPkgPath, $tgtdir) | Out-Null
}
else
{
$tgtdir = $SetupPkgPath
}
$pfxCert = Get-Item Cert:\LocalMachine\My\$SSLThumbprint -ErrorAction SilentlyContinue
if($null -eq $pfxCert)
{
throw "The certificate with thumbprint '$SSLThumbprint' doesn't exist under Cert:\LocalMachine\My"
}
if($pfxCert.Subject -eq $pfxCert.Issuer)
{
if(-not (Test-Path Cert:\LocalMachine\Root\$SSLThumbprint))
{
Write-Verbose "Installing certificate to Cert:\LocalMachine\Root"
$cerFileName = "$env:Temp\HpcPackComm.cer"
Export-Certificate -Cert "Cert:\LocalMachine\My\$SSLThumbprint" -FilePath $cerFileName | Out-Null
Import-Certificate -FilePath $cerFileName -CertStoreLocation Cert:\LocalMachine\Root | Out-Null
Remove-Item $cerFileName -Force -ErrorAction SilentlyContinue
}
}
$legacyHa = $false
$setupArg = "-unattend -Quiet -HeadNode -ClusterName:$ClusterName -SSLThumbprint:$SSLThumbprint"
if($LinuxCommOverHttp)
{
$setupArg += " -LinuxCommOverHttp"
}
if($LinuxAuthenticationKey)
{
$setupArg += " -ClusterAuthenticationKey:$LinuxAuthenticationKey"
}
if(!$EnableBuiltinHA -and $HeadNodeList -and ($HeadNodeList -ne $env:COMPUTERNAME))
{
$legacyHa = $true
$setupArg += " -HeadNodeList:`"$HeadNodeList`""
}
if($SQLServerInstance)
{
if($PSBoundParameters.ContainsKey('SQLCredential'))
{
$secinfo = "Integrated Security=False;User ID={0};Password={1}" -f $SQLCredential.UserName, $SQLCredential.GetNetworkCredential().Password
}
else
{
$secinfo = "Integrated Security=True"
}
$mgmtConstr = "Data Source=$SQLServerInstance;Initial Catalog=HpcManagement;$secinfo"
$schdConstr = "Data Source=$SQLServerInstance;Initial Catalog=HpcScheduler;$secinfo"
$monConstr = "Data Source=$SQLServerInstance;Initial Catalog=HPCMonitoring;$secinfo"
$rptConstr = "Data Source=$SQLServerInstance;Initial Catalog=HPCReporting;$secinfo"
$diagConstr = "Data Source=$SQLServerInstance;Initial Catalog=HPCDiagnostics;$secinfo"
$setupArg += " -MgmtDbConStr:`"$mgmtConstr`" -SchdDbConStr:`"$schdConstr`" -RptDbConStr:`"$rptConstr`" -DiagDbConStr:`"$diagConstr`" -MonDbConStr:`"$monConstr`""
if(-not $legacyHa)
{
$haStorageConstr = "Data Source=$SQLServerInstance;Initial Catalog=HPCHAStorage;$secinfo"
$haWitnessConstr = "Data Source=$SQLServerInstance;Initial Catalog=HPCHAWitness;$secinfo"
$setupArg += " -HAStorageDbConStr:`"$haStorageConstr`" -HAWitnessDbConStr:`"$haWitnessConstr`""
}
}
if($EnableBuiltinHA)
{
$setupVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$tgtdir\setup.exe")
if($setupVersion.ProductVersionRaw -gt "6.0.7150.0")
{
$setupArg += " -EnableBuiltinHA"
}
}
$retry = 0
$maxRetryTimes = 20
$maxRetryInterval = 60
while($true)
{
Write-Verbose "Installing HPC Pack Head Node"
$p = Start-Process -FilePath "$tgtdir\setup.exe" -ArgumentList $setupArg -PassThru -Wait
if($p.ExitCode -eq 0)
{
Write-Verbose "Succeed to Install HPC Pack Head Node"
break
}
if($p.ExitCode -eq 3010)
{
Write-Verbose "Succeed to Install HPC Pack Head Node, a reboot is required."
$global:DSCMachineStatus = 1
break
}
if($retry++ -lt $maxRetryTimes)
{
$retryInterval = [System.Math]::Min($maxRetryInterval, $retry * 10)
Write-Warning "Failed to Install HPC Pack Head Node (errCode=$($p.ExitCode)), retry after $retryInterval seconds..."
Clear-DnsClientCache
Start-Sleep -Seconds $retryInterval
}
else
{
if($p.ExitCode -eq 13818)
{
throw "Failed to Install HPC Pack Head Node (errCode=$($p.ExitCode)): the certificate doesn't meet the requirements."
}
else
{
throw "Failed to Install HPC Pack Head Node (errCode=$($p.ExitCode))"
}
}
}
}
function Test-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[string] $ClusterName,
[parameter(Mandatory = $true)]
[string] $SetupPkgPath,
[parameter(Mandatory = $true)]
[string] $SSLThumbprint,
[parameter(Mandatory = $false)]
[string] $HeadNodeList = "",
[parameter(Mandatory = $false)]
[string] $SQLServerInstance = "",
[parameter(Mandatory = $false)]
[System.Management.Automation.PSCredential] $SQLCredential,
[parameter(Mandatory = $false)]
[Boolean] $LinuxCommOverHttp = $false,
[parameter(Mandatory = $false)]
[string] $LinuxAuthenticationKey = "",
[Parameter(Mandatory=$false)]
[Boolean] $EnableBuiltinHA = $false
)
$serverGuid = "A001F5CA-5D6A-4BDA-9885-36E7A8EBABCC"
if($null -eq (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | ?{$_.UninstallString -and $_.UninstallString -match $serverGuid}))
{
return $false
}
if($HeadNodeList -and ($HeadNodeList -ne $env:COMPUTERNAME))
{
$fabricSvc = Get-Service -Name 'fabricHostSvc' -ErrorAction SilentlyContinue
return ($null -ne $fabricSvc)
}
else
{
$schedulerSvc = Get-Service -Name 'HpcScheduler' -ErrorAction SilentlyContinue
return ($null -ne $schedulerSvc)
}
}
function DownloadFile
{
param(
[parameter(Mandatory = $false)]
[System.Net.WebClient] $Downloader = $null,
[parameter(Mandatory = $true)]
[string] $SourceUrl,
[parameter(Mandatory = $true)]
[string] $DestPath
)
if($Downloader -eq $null)
{
$Downloader = New-Object System.Net.WebClient
}
$fileName = $($SourceUrl -split '/')[-1]
if(Test-Path -Path $DestPath -PathType Container)
{
$DestPath = [IO.Path]::Combine($DestPath, $fileName)
}
$downloadRetry = 0
while($true)
{
try
{
if(Test-Path -Path $DestPath)
{
Remove-Item -Path $DestPath -Force -Confirm:$false -ErrorAction SilentlyContinue
}
Write-Verbose "Downloading $SourceUrl to $DestPath(Retry=$downloadRetry)."
$Downloader.DownloadFile($SourceUrl, $DestPath)
Write-Verbose "Downloaded $SourceUrl to $DestPath."
break
}
catch
{
if($downloadRetry -lt 10)
{
Write-Verbose ("Failed to download files, retry after 20 seconds:" + $_)
Clear-DnsClientCache
Start-Sleep -Seconds 20
$downloadRetry++
}
else
{
throw "Failed to download files after 10 retries"
}
}
}
}
Export-ModuleMember -Function *-TargetResource