314 lines
17 KiB
PowerShell
314 lines
17 KiB
PowerShell
|
function Get-ServerPackageInformation {
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
The bulk of the Classify logic. Determines what versions of which packages get installed. Utilized by Classify-Packages.
|
||
|
|
||
|
.PARAMETER PackageMetadata
|
||
|
Packages object to populate.
|
||
|
|
||
|
.PARAMETER DebugMetadata
|
||
|
Meta object used to determine what goes where.
|
||
|
|
||
|
.PARAMETER BuildCheckoutDirectory
|
||
|
Directory where the code is checked out by TC. Passed through.
|
||
|
|
||
|
.PARAMETER AwsProfileName
|
||
|
Profile name to get information from AWS.
|
||
|
|
||
|
.PARAMETER UseV2PackageMetadata
|
||
|
Whether or not to use the new version of the PackageMetadata functions. Passed through.
|
||
|
|
||
|
.PARAMETER DependencyReleaseValue
|
||
|
The value of the orb release being classified. Passed through.
|
||
|
|
||
|
#>
|
||
|
[CmdletBinding()]
|
||
|
param(
|
||
|
[Parameter (Mandatory = $true)]
|
||
|
[PSObject]$PackageMetadata,
|
||
|
[Parameter (Mandatory = $true)]
|
||
|
[PSObject]$DebugMetadata,
|
||
|
[Parameter (Mandatory = $true)]
|
||
|
[string]$BuildCheckoutDirectory,
|
||
|
[Parameter (Mandatory = $true)]
|
||
|
[string]$AwsProfileName,
|
||
|
[Parameter (Mandatory = $true)]
|
||
|
[System.Management.Automation.PSCredential]$NugetCredential,
|
||
|
[switch]$UseV2PackageMetadata,
|
||
|
[Parameter (Mandatory = $true)]
|
||
|
[string]$DependencyReleaseValue
|
||
|
)
|
||
|
|
||
|
# These were set outside of the region this function came from, but are used only in this function. Nothing happens to the
|
||
|
# underlying data between when they were set and when this function was called, so declare them here instead.
|
||
|
# TODO: Consider moving these values to DebugMetadata
|
||
|
$webInstallNames = $PackageMetadata.WebPackagesToInstall.Name
|
||
|
$webUninstallNames = $PackageMetadata.WebPackagesToUninstall.Name
|
||
|
|
||
|
$appInstallNames = $PackageMetadata.AppPackagesToInstall.Name
|
||
|
$appUninstallNames = $PackageMetadata.AppPackagesToUninstall.Name
|
||
|
|
||
|
Write-Host "##teamcity[blockOpened name='Gather Information']"
|
||
|
|
||
|
$PackageMetadata = Get-EnvironmentData -packageMetadata $PackageMetadata
|
||
|
|
||
|
# Construct a map of server -> packages installed on that server.
|
||
|
$serverToPackages = @{}
|
||
|
foreach ($server in $PackageMetadata.ServersToQuery) {
|
||
|
# TODO ~ Fix this to not need the !StartsWith part
|
||
|
# ~ Relies on the package classification being right. We can just remove all SREModule types.
|
||
|
$serverToPackages[$server] = (Get-InstalledPackages -ComputerName $server).Where({ !$_.Name.StartsWith("Alkami.Installer") })
|
||
|
}
|
||
|
|
||
|
#region Filter existing packages by servertype
|
||
|
# Get the packages from each type of server.
|
||
|
if ($PackageMetadata.HasWebServers) {
|
||
|
$packages = @()
|
||
|
foreach ($server in $PackageMetadata.WebServers) {
|
||
|
$packages += @($serverToPackages[$server])
|
||
|
}
|
||
|
$DebugMetadata.WebServerPackages = @(Select-UniqueServerPackages $packages)
|
||
|
}
|
||
|
|
||
|
if ($PackageMetadata.HasAppServers) {
|
||
|
$packages = @()
|
||
|
foreach ($server in $PackageMetadata.AppServers) {
|
||
|
$packages += @($serverToPackages[$server])
|
||
|
}
|
||
|
$DebugMetadata.AppServerPackages = @(Select-UniqueServerPackages $packages)
|
||
|
}
|
||
|
|
||
|
if ($PackageMetadata.HasMicServers) {
|
||
|
$packages = @()
|
||
|
foreach ($server in $PackageMetadata.MicServers) {
|
||
|
$packages += @($serverToPackages[$server])
|
||
|
}
|
||
|
$DebugMetadata.MicServerPackages = @(Select-UniqueServerPackages $packages)
|
||
|
}
|
||
|
|
||
|
if ($PackageMetadata.HasFabServers) {
|
||
|
$packages = @()
|
||
|
foreach ($server in $PackageMetadata.FabServers) {
|
||
|
$packages += @($serverToPackages[$server])
|
||
|
}
|
||
|
$DebugMetadata.FabServerPackages = @(Select-UniqueServerPackages $packages)
|
||
|
}
|
||
|
#endregion Filter existing packages by servertype
|
||
|
|
||
|
#region Find all packages with multi-server-existing-version-mismatch for true-up
|
||
|
# Create a list of package name -> versions installed on each server.
|
||
|
# This gives a view of all of the versions of a particular package installed.
|
||
|
foreach ($serverPackages in $serverToPackages.Values) {
|
||
|
foreach ($package in $serverPackages) {
|
||
|
$packageNameLower = $package.Name.ToLower()
|
||
|
if (!$PackageMetadata.PackageToVersions.ContainsKey($packageNameLower)) {
|
||
|
$PackageMetadata.PackageToVersions[$packageNameLower] = @($package.Version)
|
||
|
} else {
|
||
|
$PackageMetadata.PackageToVersions[$packageNameLower] = $PackageMetadata.PackageToVersions[$packageNameLower] + $package.Version
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
# Limit the versions down to unique versions installed.
|
||
|
$packageToVersionsKeys = @() + $PackageMetadata.PackageToVersions.Keys; # So we aren't "changing" the keys of the map and breaking enumeration.
|
||
|
foreach ($key in $packageToVersionsKeys) {
|
||
|
$PackageMetadata.PackageToVersions[$key] = ($PackageMetadata.PackageToVersions[$key] | Select-Object -Unique)
|
||
|
}
|
||
|
#endregion Find all packages with multi-server-existing-version-mismatch for true-up
|
||
|
|
||
|
# Create a list of package names to servers the package is installed on.
|
||
|
# Also, when a FAB name is encountered, add the entire list of FAB servers.
|
||
|
foreach ($server in $serverToPackages.Keys) {
|
||
|
$serversToAdd = @($server)
|
||
|
if ($server -like "fab*") {
|
||
|
$serversToAdd = @($PackageMetadata.FabServers)
|
||
|
}
|
||
|
$serverPackages = $serverToPackages[$server]
|
||
|
foreach ($package in $serverPackages) {
|
||
|
$lowerName = $package.Name.ToLower()
|
||
|
if (!$PackageMetadata.PackageToServers.ContainsKey($lowerName)) {
|
||
|
$PackageMetadata.PackageToServers[$lowerName] = $serversToAdd
|
||
|
} else {
|
||
|
$PackageMetadata.PackageToServers[$lowerName] += $serversToAdd
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#region Filter packages down to unique packages across the entire environment
|
||
|
$allWebTierPackages = (Select-UniqueServerPackages $DebugMetadata.WebServerPackages)
|
||
|
$allAppTierPackages = (Select-UniqueServerPackages (
|
||
|
@($DebugMetadata.AppServerPackages) +
|
||
|
@($DebugMetadata.MicServerPackages) +
|
||
|
@($DebugMetadata.FabServerPackages)
|
||
|
))
|
||
|
|
||
|
# Create a map of the packages getting installed from the job parameters. We need to know which packages came from the deploy params, and which from the servers.
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.WebPackagesToInstall)) {
|
||
|
foreach ($package in $PackageMetadata.WebPackagesToInstall) {
|
||
|
$DebugMetadata.WebPackagesToInstallMap[$package.Name.ToLower()] = $package
|
||
|
}
|
||
|
}
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.AppPackagesToInstall)) {
|
||
|
foreach ($package in $PackageMetadata.AppPackagesToInstall) {
|
||
|
$DebugMetadata.AppPackagesToInstallMap[$package.Name.ToLower()] = $package
|
||
|
}
|
||
|
}
|
||
|
#endregion Filter packages down to unique packages across the entire environment
|
||
|
|
||
|
#region Determine $all___TierPackageInstalls
|
||
|
if ($PackageMetadata.ForceReinstallPackages) {
|
||
|
# It's a full deploy. (This is an implicit reproduction of the .IsOrbDeploy flag. The two should probably be consolidated at some point.)
|
||
|
# Overwrite the packages from the environment with packages intended to be installed.
|
||
|
# This will leave us with a list of things we want installed, plus the things we might force-reinstall.
|
||
|
$allWebTierPackages = (Select-InstallPackages $allWebTierPackages $PackageMetadata.WebPackagesToInstall)
|
||
|
$allAppTierPackages = (Select-InstallPackages $allAppTierPackages $PackageMetadata.AppPackagesToInstall)
|
||
|
} else {
|
||
|
# Otherwise it's an element deploy.
|
||
|
# Filter down the list of packages to the ones that are being deployed.
|
||
|
$allWebTierPackages = $PackageMetadata.WebPackagesToInstall
|
||
|
$allAppTierPackages = $PackageMetadata.AppPackagesToInstall
|
||
|
}
|
||
|
#endregion Determine $all___TierPackageInstalls
|
||
|
|
||
|
#region Exclude chocolatey if present
|
||
|
if ($null -ne ($allWebTierPackages | Where-Object { $_.Name -eq "chocolatey" })) {
|
||
|
Write-Warning "The Chocolatey Package Manager Program package (chocolatey) was passed in to be installed on the Web Tier. At this time we explicitly dissallow that. It has been skipped."
|
||
|
}
|
||
|
if ($null -ne ($allAppTierPackages | Where-Object { $_.Name -eq "chocolatey" })) {
|
||
|
Write-Warning "The Chocolatey Package Manager Program package (chocolatey) was passed in to be installed on the App Tier. At this time we explicitly dissallow that. It has been skipped."
|
||
|
}
|
||
|
|
||
|
# Remove chocolatey from the install lists.
|
||
|
$allWebTierPackages = $allWebTierPackages | Where-Object { $_.Name -ne "chocolatey" }
|
||
|
$allAppTierPackages = $allAppTierPackages | Where-Object { $_.Name -ne "chocolatey" }
|
||
|
|
||
|
#endregion Exclude chocolatey if present
|
||
|
|
||
|
|
||
|
#region Remove PackagesToUninstall from all***TierPackages
|
||
|
#TODO: Independent filter here or add to Select-InstallPackages called from Line 636-637 ?
|
||
|
#TODO: OR Add to Get-PackageInstallationData in Alkami.Powershell.Choco called from 675-677 ?
|
||
|
#endregion Remove PackagesToUninstall from all***TierPackages
|
||
|
|
||
|
$buildMappingArgs = @{
|
||
|
AllAppTierPackages = $allAppTierPackages
|
||
|
AllWebTierPackages = $allWebTierPackages
|
||
|
BuildCheckoutDirectory = $BuildCheckoutDirectory
|
||
|
DebugMetadata = $DebugMetadata
|
||
|
NugetCredential = $NugetCredential
|
||
|
PackageMetadata = $PackageMetadata
|
||
|
UseV2PackageMetadata = $UseV2PackageMetadata
|
||
|
DependencyReleaseValue = $DependencyReleaseValue
|
||
|
}
|
||
|
|
||
|
$PackageMetadata,$DebugMetadata = Get-PackageServerMapping @buildMappingArgs
|
||
|
|
||
|
$PackageMetadata = Get-BadPackages -DebugMetadata $DebugMetadata -PackageMetadata $PackageMetadata
|
||
|
|
||
|
# Strip out empty/null entries. Follow up/remove with SRE-17113. Suggestion for debugging; move this block around and see where it fails
|
||
|
[array]$PackageMetadata.WebPackagesToInstall = $PackageMetadata.WebPackagesToInstall.Where({$null -ne $_})
|
||
|
[array]$PackageMetadata.AppPackagesToInstall = $PackageMetadata.AppPackagesToInstall.Where({$null -ne $_})
|
||
|
[array]$PackageMetadata.MicPackagesToInstall = $PackageMetadata.MicPackagesToInstall.Where({$null -ne $_})
|
||
|
|
||
|
#region Doublecheck force-reinstall
|
||
|
# Keep only the packages that need to be force reinstalled, or that came from the install parameters.
|
||
|
if ($PackageMetadata.ForceReinstallPackages) {
|
||
|
$PackageMetadata.WebPackagesToInstall = $PackageMetadata.WebPackagesToInstall | Where-Object {
|
||
|
# Where package exists on a server, and will be deleted (ie: widget), but isn't in either of our lists.
|
||
|
(($_.ForceSameVersion -and ($webUninstallNames -inotcontains $_.Name -and $webInstallNames -inotcontains $_.Name))) -or
|
||
|
# Packages we're installing for some reason decided upon above.
|
||
|
($DebugMetadata.WebPackagesToInstallMap.ContainsKey($_.Name.ToLower())) }
|
||
|
$PackageMetadata.AppPackagesToInstall = $PackageMetadata.AppPackagesToInstall | Where-Object {
|
||
|
(($_.ForceSameVersion -and ($appUninstallNames -inotcontains $_.Name -and $appInstallNames -inotcontains $_.Name))) -or
|
||
|
# Packages we're installing for some reason decided upon above.
|
||
|
($DebugMetadata.AppPackagesToInstallMap.ContainsKey($_.Name.ToLower())) }
|
||
|
}
|
||
|
#endregion Doublecheck force-reinstall
|
||
|
|
||
|
#region Remove packages from the install lists that do not need to be needlessly re-installed.
|
||
|
Write-Host ("##teamcity[blockOpened name='Removing Already-Installed Packages']")
|
||
|
# Web/App package arrays here are getting null entries from *mumble mumble* somewhere...
|
||
|
# cut out the nulls before passing it along.
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.WebPackagesToInstall)) {
|
||
|
$packagesToInstall = @()
|
||
|
foreach($package in $PackageMetadata.WebPackagesToInstall){
|
||
|
if($null -ne $package){
|
||
|
$packagesToInstall += $package
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$PackageMetadata.WebPackagesToInstall = (Remove-PackagesThatAreAlreadyInstalled -packagesToInstall $packagesToInstall -packageMetadata $PackageMetadata -debugMetadata $DebugMetadata)
|
||
|
}
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.AppPackagesToInstall)) {
|
||
|
$packagesToInstall = @()
|
||
|
foreach($package in $PackageMetadata.AppPackagesToInstall){
|
||
|
if($null -ne $package){
|
||
|
$packagesToInstall += $package
|
||
|
}
|
||
|
}
|
||
|
$PackageMetadata.AppPackagesToInstall = (Remove-PackagesThatAreAlreadyInstalled -packagesToInstall $packagesToInstall -packageMetadata $PackageMetadata -debugMetadata $DebugMetadata)
|
||
|
}
|
||
|
|
||
|
# $PackageMetadata.WebPackagesToInstall = (Remove-PackagesThatAreAlreadyInstalled -packagesToInstall $PackageMetadata.WebPackagesToInstall -packageMetadata $PackageMetadata -debugMetadata $DebugMetadata)
|
||
|
# $PackageMetadata.AppPackagesToInstall = (Remove-PackagesThatAreAlreadyInstalled -packagesToInstall $PackageMetadata.AppPackagesToInstall -packageMetadata $PackageMetadata -debugMetadata $DebugMetadata)
|
||
|
Write-Host ("##teamcity[blockClosed name='Removing Already-Installed Packages']")
|
||
|
#endregion Remove packages from the install lists that do not need to be needlessly re-installed.
|
||
|
|
||
|
#region Gather AWS settings from a sample server
|
||
|
# Had to re-obtain this value here when functionalizing classify.
|
||
|
$serverToQuery = $packageMetadata.ServersToQuery | Select-Object -First 1
|
||
|
|
||
|
# Grab data from first server available
|
||
|
$awsSettings = Get-AwsSettings -serverToTest $serverToQuery -profileName $AwsProfileName
|
||
|
|
||
|
$PackageMetadata.AwsSettings = $awsSettings
|
||
|
|
||
|
#endregion Gather AWS settings from a sample server
|
||
|
|
||
|
#region Separate App-Mic/Fab installs and uninstalls.
|
||
|
# Separate out the mic/fab installs from the app installs.
|
||
|
[array]$PackageMetadata.MicPackagesToInstall = $PackageMetadata.AppPackagesToInstall | Where-Object { $_.InstallToMic -or $_.InstallToFab }
|
||
|
[array]$PackageMetadata.AppPackagesToInstall = $PackageMetadata.AppPackagesToInstall | Where-Object { $_.InstallToApp }
|
||
|
|
||
|
$newAppUninstalls = @()
|
||
|
$newMicUninstalls = @()
|
||
|
|
||
|
foreach($package in $PackageMetadata.AppPackagesToUninstall) {
|
||
|
$packageInstalledOnServers = $PackageMetadata.PackageToServers[$package.Name]
|
||
|
$installedOnAppServers = $null -ne (Select-AlkamiAppServers -servers $packageInstalledOnServers)
|
||
|
$installedOnMicServers = ($null -ne (Select-AlkamiMicServers -servers $packageInstalledOnServers)) -or
|
||
|
($null -ne (Select-AlkamiFabServers -servers $packageInstalledOnServers))
|
||
|
|
||
|
if($installedOnAppServers) {
|
||
|
$newAppUninstalls += $package
|
||
|
}
|
||
|
if($installedOnMicServers) {
|
||
|
$newMicUninstalls += $package
|
||
|
}
|
||
|
}
|
||
|
$PackageMetadata.AppPackagesToUninstall = $newAppUninstalls
|
||
|
$PackageMetadata.MicPackagesToUninstall = $newMicUninstalls
|
||
|
|
||
|
# Add the bad packages to uninstall to the uninstall lists.
|
||
|
# This must happen underneath the app/mic uninstall separation, so we don't remove a valid package from a mic/app server.
|
||
|
# This preserves explicit package uninstalls, but allows for specific removal of bad packages.
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.BadWebPackagesToUninstall)) { $PackageMetadata.WebPackagesToUninstall += $PackageMetadata.BadWebPackagesToUninstall; }
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.BadAppPackagesToUninstall)) { $PackageMetadata.AppPackagesToUninstall += $PackageMetadata.BadAppPackagesToUninstall; }
|
||
|
if (!(Test-IsCollectionNullOrEmpty $PackageMetadata.BadMicPackagesToUninstall)) { $PackageMetadata.MicPackagesToUninstall += $PackageMetadata.BadMicPackagesToUninstall; }
|
||
|
|
||
|
#endregion Separate Mic/Fab installs/uninstalls.
|
||
|
|
||
|
$packageMetadata, $debugMetadata = Add-OldHotfixPackagesToUninstallList -DependencyReleaseValue $DependencyReleaseValue -PackageMetadata $packageMetadata -DebugMetadata $debugMetadata
|
||
|
|
||
|
#region Final determination of what types of installs we are doing
|
||
|
$PackageMetadata.HasWebInstalls = !(Test-IsCollectionNullOrEmpty $PackageMetadata.WebPackagesToInstall)
|
||
|
$PackageMetadata.HasWebUninstalls = !(Test-IsCollectionNullOrEmpty $PackageMetadata.WebPackagesToUninstall)
|
||
|
$PackageMetadata.HasAppInstalls = !(Test-IsCollectionNullOrEmpty $PackageMetadata.AppPackagesToInstall)
|
||
|
$PackageMetadata.HasAppUninstalls = !(Test-IsCollectionNullOrEmpty $PackageMetadata.AppPackagesToUninstall)
|
||
|
$PackageMetadata.HasMicInstalls = !(Test-IsCollectionNullOrEmpty $PackageMetadata.MicPackagesToInstall)
|
||
|
$PackageMetadata.HasMicUninstalls = !(Test-IsCollectionNullOrEmpty $PackageMetadata.MicPackagesToUninstall)
|
||
|
#endregion Final determination of what types of installs we are doing
|
||
|
|
||
|
return $PackageMetadata, $DebugMetadata
|
||
|
|
||
|
Write-Host ("##teamcity[blockClosed name='Gather Information']")
|
||
|
}
|