PackageModel/Support/Package/Eigenverft.Manifested.Sandbox.PackageModel.Ownership.ps1
|
<#
Eigenverft.Manifested.Sandbox.PackageModel.Ownership #> function Get-PackageModelInstallSlotId { <# .SYNOPSIS Builds the logical PackageModel install-slot id for a result. .DESCRIPTION Combines the definition id, release track, and flavor into the stable install slot identity used by the ownership index. .PARAMETER PackageModelResult The current PackageModel result object. .EXAMPLE Get-PackageModelInstallSlotId -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) $definitionId = [string]$PackageModelResult.DefinitionId $releaseTrack = if ($PackageModelResult.Package -and $PackageModelResult.Package.PSObject.Properties['releaseTrack']) { [string]$PackageModelResult.Package.releaseTrack } else { [string]$PackageModelResult.ReleaseTrack } $flavor = if ($PackageModelResult.Package -and $PackageModelResult.Package.PSObject.Properties['flavor']) { [string]$PackageModelResult.Package.flavor } else { 'default' } return ('{0}:{1}:{2}' -f $definitionId, $releaseTrack, $flavor) } function Get-PackageModelOwnershipIndex { <# .SYNOPSIS Loads the PackageModel ownership index. .DESCRIPTION Returns the configured central ownership index document, or an empty record set when the index file does not exist yet. .PARAMETER PackageModelConfig The resolved PackageModel config object. .EXAMPLE Get-PackageModelOwnershipIndex -PackageModelConfig $config #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelConfig ) $indexPath = $PackageModelConfig.OwnershipIndexFilePath if ([string]::IsNullOrWhiteSpace($indexPath)) { throw 'PackageModel ownership index path is not configured.' } if (-not (Test-Path -LiteralPath $indexPath -PathType Leaf)) { return [pscustomobject]@{ Path = $indexPath Records = @() } } $documentInfo = Read-PackageModelJsonDocument -Path $indexPath $records = if ($documentInfo.Document.PSObject.Properties['records']) { @($documentInfo.Document.records) } else { @() } return [pscustomobject]@{ Path = $documentInfo.Path Records = $records } } function Save-PackageModelOwnershipIndex { <# .SYNOPSIS Writes the PackageModel ownership index to disk. .DESCRIPTION Persists the normalized ownership index document to the configured index path. .PARAMETER IndexPath The target index file path. .PARAMETER Records The ownership records to persist. .EXAMPLE Save-PackageModelOwnershipIndex -IndexPath $path -Records $records #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$IndexPath, [Parameter(Mandatory = $true)] [object[]]$Records ) $directoryPath = Split-Path -Parent $IndexPath if (-not [string]::IsNullOrWhiteSpace($directoryPath)) { $null = New-Item -ItemType Directory -Path $directoryPath -Force } [ordered]@{ records = @($Records) } | ConvertTo-Json -Depth 20 | Set-Content -LiteralPath $IndexPath -Encoding UTF8 } function Get-PackageModelOwnershipRecord { <# .SYNOPSIS Returns the ownership record for the current install slot and install directory. .DESCRIPTION Finds the best matching ownership record for a PackageModel result by using the logical install slot together with the discovered install directory. .PARAMETER PackageModelResult The current PackageModel result object. .EXAMPLE Get-PackageModelOwnershipRecord -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) $existingPackage = $PackageModelResult.ExistingPackage if (-not $existingPackage -or [string]::IsNullOrWhiteSpace($existingPackage.InstallDirectory)) { return $null } $index = Get-PackageModelOwnershipIndex -PackageModelConfig $PackageModelResult.PackageModelConfig $installSlotId = Get-PackageModelInstallSlotId -PackageModelResult $PackageModelResult $normalizedInstallDirectory = [System.IO.Path]::GetFullPath($existingPackage.InstallDirectory) foreach ($record in @($index.Records)) { if ([string]::Equals([string]$record.installSlotId, $installSlotId, [System.StringComparison]::OrdinalIgnoreCase) -and [string]::Equals([string]$record.installDirectory, $normalizedInstallDirectory, [System.StringComparison]::OrdinalIgnoreCase)) { return $record } } return $null } function Resolve-PackageModelOwnershipKindText { [CmdletBinding()] param( [AllowNull()] [string]$OwnershipKind ) switch -Exact ([string]$OwnershipKind) { 'ManagedInstalled' { return 'PackageModelInstalled' } 'ManagedReused' { return 'PackageModelInstalled' } default { return $OwnershipKind } } } function Classify-PackageModelExistingPackage { <# .SYNOPSIS Classifies a discovered existing install against the ownership index. .DESCRIPTION Attaches ownership classification data to the current existing install so later helpers can decide whether the install is PackageModel-owned, adopted, or external. .PARAMETER PackageModelResult The PackageModel result object to enrich. .EXAMPLE Classify-PackageModelExistingPackage -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) if (-not $PackageModelResult.ExistingPackage) { $PackageModelResult.Ownership = [pscustomobject]@{ IndexPath = $PackageModelResult.PackageModelConfig.OwnershipIndexFilePath InstallSlotId = Get-PackageModelInstallSlotId -PackageModelResult $PackageModelResult Classification = 'NotFound' OwnershipRecord = $null } return $PackageModelResult } $record = Get-PackageModelOwnershipRecord -PackageModelResult $PackageModelResult $classification = if ($record -or [string]::Equals([string]$PackageModelResult.ExistingPackage.SearchKind, 'packageModelTargetInstallPath', [System.StringComparison]::OrdinalIgnoreCase)) { 'PackageModelOwned' } else { 'ExternalInstall' } $installSlotId = Get-PackageModelInstallSlotId -PackageModelResult $PackageModelResult $PackageModelResult.Ownership = [pscustomobject]@{ IndexPath = $PackageModelResult.PackageModelConfig.OwnershipIndexFilePath InstallSlotId = $installSlotId Classification = $classification OwnershipRecord = $record } $PackageModelResult.ExistingPackage.Classification = $classification $PackageModelResult.ExistingPackage.OwnershipRecord = $record $ownershipKindText = if ($record -and $record.PSObject.Properties['ownershipKind']) { Resolve-PackageModelOwnershipKindText -OwnershipKind ([string]$record.ownershipKind) } else { '<none>' } Write-PackageModelExecutionMessage -Message ("[STATE] Ownership classification for installSlotId '{0}' is '{1}' (ownershipKind='{2}')." -f $installSlotId, $classification, $ownershipKindText) return $PackageModelResult } function Update-PackageModelOwnershipRecord { <# .SYNOPSIS Updates the central ownership record after a PackageModel run. .DESCRIPTION Writes or refreshes the ownership record for PackageModel-owned installs, PackageModel-owned reuse, and adopted external installs. External installs that were ignored are not written to the central index. .PARAMETER PackageModelResult The finalized PackageModel result object. .EXAMPLE Update-PackageModelOwnershipRecord -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) if (-not $PackageModelResult.Validation -or -not $PackageModelResult.Validation.Accepted) { return $PackageModelResult } $ownershipKind = switch -Exact ([string]$PackageModelResult.InstallOrigin) { 'PackageModelInstalled' { 'PackageModelInstalled'; break } 'PackageModelReused' { 'PackageModelInstalled'; break } 'AdoptedExternal' { 'AdoptedExternal'; break } default { $null } } if ([string]::IsNullOrWhiteSpace($ownershipKind)) { return $PackageModelResult } $index = Get-PackageModelOwnershipIndex -PackageModelConfig $PackageModelResult.PackageModelConfig $normalizedInstallDirectory = [System.IO.Path]::GetFullPath($PackageModelResult.InstallDirectory) $installSlotId = Get-PackageModelInstallSlotId -PackageModelResult $PackageModelResult $records = @( foreach ($record in @($index.Records)) { $sameInstallSlot = [string]::Equals([string]$record.installSlotId, $installSlotId, [System.StringComparison]::OrdinalIgnoreCase) $sameInstallDirectory = [string]::Equals([string]$record.installDirectory, $normalizedInstallDirectory, [System.StringComparison]::OrdinalIgnoreCase) if (-not $sameInstallSlot -and -not $sameInstallDirectory) { $record } } ) $newRecord = [pscustomobject]@{ installSlotId = $installSlotId definitionId = $PackageModelResult.DefinitionId releaseTrack = if ($PackageModelResult.Package -and $PackageModelResult.Package.PSObject.Properties['releaseTrack']) { [string]$PackageModelResult.Package.releaseTrack } else { [string]$PackageModelResult.ReleaseTrack } flavor = if ($PackageModelResult.Package -and $PackageModelResult.Package.PSObject.Properties['flavor']) { [string]$PackageModelResult.Package.flavor } else { $null } currentReleaseId = $PackageModelResult.PackageId currentVersion = $PackageModelResult.PackageVersion installDirectory = $normalizedInstallDirectory ownershipKind = $ownershipKind updatedAtUtc = [DateTime]::UtcNow.ToString('o') } $records += $newRecord Save-PackageModelOwnershipIndex -IndexPath $index.Path -Records $records $PackageModelResult.Ownership = [pscustomobject]@{ IndexPath = $index.Path InstallSlotId = $installSlotId Classification = if ($ownershipKind -eq 'AdoptedExternal') { 'AdoptedExternal' } else { 'PackageModelOwned' } OwnershipRecord = $newRecord } Write-PackageModelExecutionMessage -Message ("[STATE] Updated ownership record for installSlotId '{0}' with ownershipKind='{1}' at '{2}'." -f $installSlotId, $ownershipKind, $index.Path) return $PackageModelResult } |