PackageModel/Support/Package/Eigenverft.Manifested.Sandbox.PackageModel.Install.ps1
|
<#
Eigenverft.Manifested.Sandbox.PackageModel.Install #> function Resolve-PackageModelExistingInstallRoot { <# .SYNOPSIS Resolves an install directory from a discovered existing-install candidate path. .DESCRIPTION Uses the existing-install root rules to turn a discovered file path such as `code.cmd` into the install directory that owns that file. .PARAMETER ExistingInstallDiscovery The existing-install discovery definition object. .PARAMETER CandidatePath The discovered file or directory path. .EXAMPLE Resolve-PackageModelExistingInstallRoot -ExistingInstallDiscovery $package.existingInstallDiscovery -CandidatePath $candidatePath #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$ExistingInstallDiscovery, [Parameter(Mandatory = $true)] [string]$CandidatePath ) if (Test-Path -LiteralPath $CandidatePath -PathType Container) { return (Resolve-Path -LiteralPath $CandidatePath -ErrorAction Stop).Path } $leafName = Split-Path -Leaf $CandidatePath foreach ($rule in @($ExistingInstallDiscovery.installRootRules)) { if (-not $rule.PSObject.Properties['match'] -or $null -eq $rule.match) { continue } $matchKind = if ($rule.match.PSObject.Properties['kind']) { [string]$rule.match.kind } else { $null } $matchValue = if ($rule.match.PSObject.Properties['value']) { [string]$rule.match.value } else { $null } if ([string]::Equals($matchKind, 'fileName', [System.StringComparison]::OrdinalIgnoreCase) -and [string]::Equals($matchValue, $leafName, [System.StringComparison]::OrdinalIgnoreCase)) { $candidateDirectory = Split-Path -Parent $CandidatePath $installRootRelativePath = if ($rule.PSObject.Properties['installRootRelativePath']) { [string]$rule.installRootRelativePath } else { '.' } return [System.IO.Path]::GetFullPath((Join-Path $candidateDirectory $installRootRelativePath)) } } return (Split-Path -Parent $CandidatePath) } function Find-PackageModelExistingPackage { <# .SYNOPSIS Finds an existing package install that may be reused or adopted. .DESCRIPTION Searches command, path, and directory candidates from the release existingInstallDiscovery block and attaches the first matching install directory to the PackageModel result. .PARAMETER PackageModelResult The PackageModel result object to enrich. .EXAMPLE Find-PackageModelExistingPackage -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) if (-not [string]::IsNullOrWhiteSpace([string]$PackageModelResult.InstallDirectory) -and (Test-Path -LiteralPath $PackageModelResult.InstallDirectory -PathType Container)) { $resolvedPackageModelOwnedInstallDirectory = [System.IO.Path]::GetFullPath([string]$PackageModelResult.InstallDirectory) $PackageModelResult.ExistingPackage = [pscustomobject]@{ SearchKind = 'packageModelTargetInstallPath' CandidatePath = $resolvedPackageModelOwnedInstallDirectory InstallDirectory = $resolvedPackageModelOwnedInstallDirectory Decision = 'Pending' Validation = $null Classification = $null OwnershipRecord = $null } Write-PackageModelExecutionMessage -Message ("[DISCOVERY] Found PackageModel target install directory '{0}'." -f $resolvedPackageModelOwnedInstallDirectory) return $PackageModelResult } $package = $PackageModelResult.Package if (-not $package -or -not $package.PSObject.Properties['existingInstallDiscovery'] -or $null -eq $package.existingInstallDiscovery) { return $PackageModelResult } $existingInstallDiscovery = $package.existingInstallDiscovery if ($existingInstallDiscovery.PSObject.Properties['enableDetection'] -and (-not [bool]$existingInstallDiscovery.enableDetection)) { return $PackageModelResult } foreach ($searchLocation in @($existingInstallDiscovery.searchLocations)) { $candidatePath = $null switch -Exact ([string]$searchLocation.kind) { 'command' { if (-not $searchLocation.PSObject.Properties['name'] -or [string]::IsNullOrWhiteSpace([string]$searchLocation.name)) { throw "PackageModel existingInstallDiscovery search for release '$($package.id)' is missing command name." } $candidatePath = Get-ManifestedResolvedApplicationPath -CommandName ([string]$searchLocation.name) } 'path' { if (-not $searchLocation.PSObject.Properties['path'] -or [string]::IsNullOrWhiteSpace([string]$searchLocation.path)) { throw "PackageModel existingInstallDiscovery search for release '$($package.id)' is missing path." } $resolvedPath = Resolve-PackageModelPathValue -PathValue ([string]$searchLocation.path) if (Test-Path -LiteralPath $resolvedPath) { $candidatePath = $resolvedPath } } 'directory' { if (-not $searchLocation.PSObject.Properties['path'] -or [string]::IsNullOrWhiteSpace([string]$searchLocation.path)) { throw "PackageModel existingInstallDiscovery search for release '$($package.id)' is missing directory path." } $resolvedPath = Resolve-PackageModelPathValue -PathValue ([string]$searchLocation.path) if (Test-Path -LiteralPath $resolvedPath -PathType Container) { $candidatePath = $resolvedPath } } default { throw "Unsupported PackageModel existingInstallDiscovery search kind '$($searchLocation.kind)'." } } if ([string]::IsNullOrWhiteSpace($candidatePath)) { continue } $installDirectory = Resolve-PackageModelExistingInstallRoot -ExistingInstallDiscovery $existingInstallDiscovery -CandidatePath $candidatePath if (-not (Test-Path -LiteralPath $installDirectory -PathType Container)) { continue } $PackageModelResult.ExistingPackage = [pscustomobject]@{ SearchKind = $searchLocation.kind CandidatePath = $candidatePath InstallDirectory = $installDirectory Decision = 'Pending' Validation = $null Classification = $null OwnershipRecord = $null } Write-PackageModelExecutionMessage -Message ("[DISCOVERY] Found existing package candidate '{0}' via '{1}'." -f $candidatePath, $searchLocation.kind) return $PackageModelResult } return $PackageModelResult } function Resolve-PackageModelExistingPackageDecision { <# .SYNOPSIS Evaluates how PackageModel should react to a discovered existing install. .DESCRIPTION Validates the discovered install, combines the result with ownership classification and release-specific policy switches, and records whether the current run should reuse, adopt, ignore, or replace the install. .PARAMETER PackageModelResult The PackageModel result object to enrich. .EXAMPLE Resolve-PackageModelExistingPackageDecision -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) if (-not $PackageModelResult.ExistingPackage) { return $PackageModelResult } $package = $PackageModelResult.Package $existingInstallPolicy = if ($package.PSObject.Properties['existingInstallPolicy']) { $package.existingInstallPolicy } else { [pscustomobject]@{} } $originalInstallDirectory = $PackageModelResult.InstallDirectory $PackageModelResult.InstallDirectory = $PackageModelResult.ExistingPackage.InstallDirectory $PackageModelResult = Test-PackageModelInstalledPackage -PackageModelResult $PackageModelResult $PackageModelResult.ExistingPackage.Validation = $PackageModelResult.Validation if (-not $PackageModelResult.Validation.Accepted) { $PackageModelResult.ExistingPackage.Decision = 'ExistingInstallValidationFailed' $PackageModelResult.InstallDirectory = $originalInstallDirectory $PackageModelResult.Validation = $null return $PackageModelResult } $ownershipRecord = if ($PackageModelResult.Ownership -and $PackageModelResult.Ownership.OwnershipRecord) { $PackageModelResult.Ownership.OwnershipRecord } else { $null } $classification = if ($PackageModelResult.Ownership -and $PackageModelResult.Ownership.Classification) { [string]$PackageModelResult.Ownership.Classification } else { 'ExternalInstall' } $allowAdoptExternal = $false if ($existingInstallPolicy.PSObject.Properties['allowAdoptExternal']) { $allowAdoptExternal = [bool]$existingInstallPolicy.allowAdoptExternal } $upgradeAdoptedInstall = $false if ($existingInstallPolicy.PSObject.Properties['upgradeAdoptedInstall']) { $upgradeAdoptedInstall = [bool]$existingInstallPolicy.upgradeAdoptedInstall } $requirePackageModelOwnership = $false if ($existingInstallPolicy.PSObject.Properties['requirePackageModelOwnership']) { $requirePackageModelOwnership = [bool]$existingInstallPolicy.requirePackageModelOwnership } $sameRelease = $false if ($ownershipRecord) { $sameRelease = [string]::Equals([string]$ownershipRecord.currentReleaseId, [string]$PackageModelResult.PackageId, [System.StringComparison]::OrdinalIgnoreCase) -and [string]::Equals([string]$ownershipRecord.currentVersion, [string]$PackageModelResult.PackageVersion, [System.StringComparison]::OrdinalIgnoreCase) } if ([string]::Equals($classification, 'PackageModelOwned', [System.StringComparison]::OrdinalIgnoreCase) -and -not $ownershipRecord) { $PackageModelResult.ExistingPackage.Decision = 'ReusePackageModelOwned' $PackageModelResult.InstallOrigin = 'PackageModelReused' Write-PackageModelExecutionMessage -Message ("[DECISION] Reusing PackageModel-owned target install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}' with installOrigin='{1}'." -f $PackageModelResult.ExistingPackage.Decision, $PackageModelResult.InstallOrigin) return $PackageModelResult } if ([string]::Equals($classification, 'PackageModelOwned', [System.StringComparison]::OrdinalIgnoreCase) -and $ownershipRecord) { if ([string]::Equals([string]$ownershipRecord.ownershipKind, 'AdoptedExternal', [System.StringComparison]::OrdinalIgnoreCase)) { if ($sameRelease -or (-not $upgradeAdoptedInstall)) { $PackageModelResult.ExistingPackage.Decision = 'AdoptExternal' $PackageModelResult.InstallOrigin = 'AdoptedExternal' Write-PackageModelExecutionMessage -Message ("[DECISION] Reusing adopted external install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}' with installOrigin='{1}'." -f $PackageModelResult.ExistingPackage.Decision, $PackageModelResult.InstallOrigin) return $PackageModelResult } $PackageModelResult.ExistingPackage.Decision = 'UpgradeAdoptedInstall' $PackageModelResult.InstallDirectory = $originalInstallDirectory $PackageModelResult.Validation = $null Write-PackageModelExecutionMessage -Level 'WRN' -Message ("[DECISION] Replacing adopted install at '{0}' with a PackageModel-owned install." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}'." -f $PackageModelResult.ExistingPackage.Decision) return $PackageModelResult } if ($sameRelease) { $PackageModelResult.ExistingPackage.Decision = 'ReusePackageModelOwned' $PackageModelResult.InstallOrigin = 'PackageModelReused' Write-PackageModelExecutionMessage -Message ("[DECISION] Reusing PackageModel-owned install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}' with installOrigin='{1}'." -f $PackageModelResult.ExistingPackage.Decision, $PackageModelResult.InstallOrigin) return $PackageModelResult } $PackageModelResult.ExistingPackage.Decision = 'ReplacePackageModelOwnedInstall' $PackageModelResult.InstallDirectory = $originalInstallDirectory $PackageModelResult.Validation = $null Write-PackageModelExecutionMessage -Level 'WRN' -Message ("[DECISION] Replacing outdated PackageModel-owned install at '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}'." -f $PackageModelResult.ExistingPackage.Decision) return $PackageModelResult } if ($requirePackageModelOwnership) { $PackageModelResult.ExistingPackage.Decision = 'ExternalIgnored' $PackageModelResult.InstallDirectory = $originalInstallDirectory $PackageModelResult.Validation = $null Write-PackageModelExecutionMessage -Level 'WRN' -Message ("[DECISION] Ignoring external install '{0}' because PackageModel ownership is required." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}'." -f $PackageModelResult.ExistingPackage.Decision) return $PackageModelResult } if ($allowAdoptExternal) { $PackageModelResult.ExistingPackage.Decision = 'AdoptExternal' $PackageModelResult.InstallOrigin = 'AdoptedExternal' Write-PackageModelExecutionMessage -Message ("[DECISION] Adopting external install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}' with installOrigin='{1}'." -f $PackageModelResult.ExistingPackage.Decision, $PackageModelResult.InstallOrigin) return $PackageModelResult } $PackageModelResult.ExistingPackage.Decision = 'ExternalIgnored' $PackageModelResult.InstallDirectory = $originalInstallDirectory $PackageModelResult.Validation = $null Write-PackageModelExecutionMessage -Level 'WRN' -Message ("[DECISION] Ignoring external install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) Write-PackageModelExecutionMessage -Message ("[STATE] Existing install decision resolved to '{0}'." -f $PackageModelResult.ExistingPackage.Decision) return $PackageModelResult } function Get-PackageModelOwnedInstallStatus { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) if ($PackageModelResult.ExistingPackage) { switch -Exact ([string]$PackageModelResult.ExistingPackage.Decision) { 'ExistingInstallValidationFailed' { if ([string]::Equals([string]$PackageModelResult.ExistingPackage.SearchKind, 'packageModelTargetInstallPath', [System.StringComparison]::OrdinalIgnoreCase)) { return 'RepairedPackageModelOwnedInstall' } } 'ReplacePackageModelOwnedInstall' { return 'ReplacedPackageModelOwnedInstall' } 'UpgradeAdoptedInstall' { return 'ReplacedAdoptedInstall' } } } return 'Installed' } function Install-PackageModelArchive { <# .SYNOPSIS Installs a package by expanding an archive into the install directory. .DESCRIPTION Expands the saved package file into a stage directory, promotes the expanded root into the final install directory, and creates any extra directories that the install block requests. .PARAMETER PackageModelResult The PackageModel result object to install. .EXAMPLE Install-PackageModelArchive -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) if ([string]::IsNullOrWhiteSpace($PackageModelResult.PackageFilePath) -or -not (Test-Path -LiteralPath $PackageModelResult.PackageFilePath)) { throw "PackageModel archive install for '$($PackageModelResult.PackageId)' requires a saved package file." } $install = $PackageModelResult.Package.install $stageInfo = $null try { $stageInfo = Expand-ManifestedArchiveToStage -PackagePath $PackageModelResult.PackageFilePath -Prefix 'packagemodel' $expandedRoot = $stageInfo.ExpandedRoot if ($install.PSObject.Properties['expandedRoot'] -and -not [string]::IsNullOrWhiteSpace([string]$install.expandedRoot) -and [string]$install.expandedRoot -ne 'auto') { $expandedRoot = Join-Path $stageInfo.StagePath (([string]$install.expandedRoot) -replace '/', '\') } if (-not (Test-Path -LiteralPath $expandedRoot -PathType Container)) { throw "Expanded package root '$expandedRoot' was not found for '$($PackageModelResult.PackageId)'." } $null = New-Item -ItemType Directory -Path (Split-Path -Parent $PackageModelResult.InstallDirectory) -Force if (Test-Path -LiteralPath $PackageModelResult.InstallDirectory) { Remove-Item -LiteralPath $PackageModelResult.InstallDirectory -Recurse -Force } New-Item -ItemType Directory -Path $PackageModelResult.InstallDirectory -Force | Out-Null Get-ChildItem -LiteralPath $expandedRoot -Force | ForEach-Object { Move-Item -LiteralPath $_.FullName -Destination $PackageModelResult.InstallDirectory -Force } foreach ($relativePath in @($install.createDirectories)) { $targetDirectory = Join-Path $PackageModelResult.InstallDirectory (([string]$relativePath) -replace '/', '\') New-Item -ItemType Directory -Path $targetDirectory -Force | Out-Null } } finally { if ($stageInfo) { Remove-ManifestedPath -Path $stageInfo.StagePath | Out-Null } } return [pscustomobject]@{ Status = Get-PackageModelOwnedInstallStatus -PackageModelResult $PackageModelResult InstallKind = 'expandArchive' InstallDirectory = $PackageModelResult.InstallDirectory ReusedExisting = $false } } function Invoke-PackageModelInstallerProcess { <# .SYNOPSIS Runs an installer-style package command and waits for completion. .DESCRIPTION Starts the configured installer command, applies timeout and exit-code rules, and returns the install log path and restart flag when configured. .PARAMETER PackageModelResult The PackageModel result object that owns the install. .EXAMPLE Invoke-PackageModelInstallerProcess -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) $install = $PackageModelResult.Package.install $commandPath = if ($install.PSObject.Properties['commandPath'] -and -not [string]::IsNullOrWhiteSpace([string]$install.commandPath)) { Resolve-PackageModelTemplateText -Text ([string]$install.commandPath) -PackageModelConfig $PackageModelResult.PackageModelConfig -Package $PackageModelResult.Package } else { $PackageModelResult.PackageFilePath } $timestamp = (Get-Date -Format 'yyyyMMdd-HHmmss') $logPath = $null if ($install.PSObject.Properties['logRelativePath'] -and -not [string]::IsNullOrWhiteSpace([string]$install.logRelativePath)) { $logRelativePath = Resolve-PackageModelTemplateText -Text ([string]$install.logRelativePath) -PackageModelConfig $PackageModelResult.PackageModelConfig -Package $PackageModelResult.Package -ExtraTokens @{ timestamp = $timestamp } $logPath = [System.IO.Path]::GetFullPath((Join-Path $PackageModelResult.PackageModelConfig.PreferredTargetInstallRootDirectory ($logRelativePath -replace '/', '\'))) $null = New-Item -ItemType Directory -Path (Split-Path -Parent $logPath) -Force } $commandArguments = @() foreach ($argument in @($install.commandArguments)) { $commandArguments += (Resolve-PackageModelTemplateText -Text ([string]$argument) -PackageModelConfig $PackageModelResult.PackageModelConfig -Package $PackageModelResult.Package -ExtraTokens @{ packageFilePath = $PackageModelResult.PackageFilePath installDirectory = $PackageModelResult.InstallDirectory installWorkspaceDirectory = $PackageModelResult.InstallWorkspaceDirectory downloadDirectory = $PackageModelResult.InstallWorkspaceDirectory logPath = $logPath timestamp = $timestamp }) } $timeoutSec = if ($install.PSObject.Properties['timeoutSec']) { [int]$install.timeoutSec } else { 300 } $successExitCodes = if ($install.PSObject.Properties['successExitCodes']) { @($install.successExitCodes | ForEach-Object { [int]$_ }) } else { @(0) } $restartExitCodes = if ($install.PSObject.Properties['restartExitCodes']) { @($install.restartExitCodes | ForEach-Object { [int]$_ }) } else { @() } $null = New-Item -ItemType Directory -Path $PackageModelResult.InstallDirectory -Force $process = Start-Process -FilePath $commandPath -ArgumentList $commandArguments -WorkingDirectory $PackageModelResult.InstallDirectory -PassThru if (-not $process.WaitForExit($timeoutSec * 1000)) { try { Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue } catch { } throw "PackageModel installer command exceeded the timeout of $timeoutSec seconds." } $process.Refresh() $exitCode = [int]$process.ExitCode $acceptedExitCodes = @($successExitCodes) + @($restartExitCodes) if ($exitCode -notin $acceptedExitCodes) { throw "PackageModel installer command failed with exit code $exitCode." } return [pscustomobject]@{ ExitCode = $exitCode RestartRequired = ($exitCode -in $restartExitCodes) LogPath = $logPath CommandPath = $commandPath CommandArguments = @($commandArguments) } } function Install-PackageModelPackageManagerPackage { <# .SYNOPSIS Installs a package through a package-manager command. .DESCRIPTION Runs the configured package-manager command with tokenized arguments and uses the install directory as the default working directory. .PARAMETER PackageModelResult The PackageModel result object to install. .EXAMPLE Install-PackageModelPackageManagerPackage -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) $install = $PackageModelResult.Package.install if (-not $install.PSObject.Properties['managerCommandPath'] -or [string]::IsNullOrWhiteSpace([string]$install.managerCommandPath)) { throw "PackageModel package-manager install for '$($PackageModelResult.PackageId)' requires install.managerCommandPath." } $managerCommandPath = Resolve-PackageModelTemplateText -Text ([string]$install.managerCommandPath) -PackageModelConfig $PackageModelResult.PackageModelConfig -Package $PackageModelResult.Package $commandArguments = @() foreach ($argument in @($install.commandArguments)) { $commandArguments += (Resolve-PackageModelTemplateText -Text ([string]$argument) -PackageModelConfig $PackageModelResult.PackageModelConfig -Package $PackageModelResult.Package -ExtraTokens @{ packageSpec = if ($install.PSObject.Properties['packageSpec']) { [string]$install.packageSpec } else { $null } packageFilePath = $PackageModelResult.PackageFilePath installDirectory = $PackageModelResult.InstallDirectory installWorkspaceDirectory = $PackageModelResult.InstallWorkspaceDirectory downloadDirectory = $PackageModelResult.InstallWorkspaceDirectory }) } $null = New-Item -ItemType Directory -Path $PackageModelResult.InstallDirectory -Force Push-Location $PackageModelResult.InstallDirectory try { & $managerCommandPath @commandArguments $exitCode = $LASTEXITCODE if ($null -eq $exitCode) { $exitCode = 0 } } finally { Pop-Location } $successExitCodes = if ($install.PSObject.Properties['successExitCodes']) { @($install.successExitCodes | ForEach-Object { [int]$_ }) } else { @(0) } if ($exitCode -notin $successExitCodes) { throw "PackageModel package-manager install failed with exit code $exitCode." } return [pscustomobject]@{ Status = Get-PackageModelOwnedInstallStatus -PackageModelResult $PackageModelResult InstallKind = 'packageManagerInstall' InstallDirectory = $PackageModelResult.InstallDirectory ReusedExisting = $false CommandPath = $managerCommandPath CommandArguments = @($commandArguments) ExitCode = $exitCode } } function Install-PackageModelPackage { <# .SYNOPSIS Installs or reuses the selected package. .DESCRIPTION Reuses or adopts a valid existing install when the earlier ownership/policy decision allows it, otherwise executes the configured install kind and attaches the install result to the PackageModel result object. .PARAMETER PackageModelResult The PackageModel result object to enrich. .EXAMPLE Install-PackageModelPackage -PackageModelResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageModelResult ) $package = $PackageModelResult.Package $install = $package.install if (-not $install -or -not $install.PSObject.Properties['kind']) { throw "PackageModel release '$($package.id)' does not define install.kind." } if ($PackageModelResult.ExistingPackage -and $PackageModelResult.ExistingPackage.Decision -eq 'ReusePackageModelOwned') { $PackageModelResult.InstallDirectory = $PackageModelResult.ExistingPackage.InstallDirectory $PackageModelResult.InstallOrigin = 'PackageModelReused' $PackageModelResult.Install = [pscustomobject]@{ Status = 'ReusedPackageModelOwned' InstallKind = 'existingInstall' InstallDirectory = $PackageModelResult.ExistingPackage.InstallDirectory ReusedExisting = $true CandidatePath = $PackageModelResult.ExistingPackage.CandidatePath } $PackageModelResult.Validation = $PackageModelResult.ExistingPackage.Validation Write-PackageModelExecutionMessage -Message ("[ACTION] Reused PackageModel-owned install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) return $PackageModelResult } if ($PackageModelResult.ExistingPackage -and $PackageModelResult.ExistingPackage.Decision -eq 'AdoptExternal') { $PackageModelResult.InstallDirectory = $PackageModelResult.ExistingPackage.InstallDirectory $PackageModelResult.InstallOrigin = 'AdoptedExternal' $PackageModelResult.Install = [pscustomobject]@{ Status = 'AdoptedExternal' InstallKind = 'existingInstall' InstallDirectory = $PackageModelResult.ExistingPackage.InstallDirectory ReusedExisting = $true CandidatePath = $PackageModelResult.ExistingPackage.CandidatePath } $PackageModelResult.Validation = $PackageModelResult.ExistingPackage.Validation Write-PackageModelExecutionMessage -Message ("[ACTION] Adopted external install '{0}'." -f $PackageModelResult.ExistingPackage.InstallDirectory) return $PackageModelResult } if ([string]::Equals([string]$install.kind, 'reuseExisting', [System.StringComparison]::OrdinalIgnoreCase)) { throw "PackageModel release '$($package.id)' requires an existing install, but no reusable install passed validation." } if ($PackageModelResult.PackageFileSave -and -not $PackageModelResult.PackageFileSave.Success) { throw $PackageModelResult.PackageFileSave.ErrorMessage } switch -Exact ([string]$install.kind) { 'expandArchive' { Write-PackageModelExecutionMessage -Message ("[ACTION] Installing package archive into '{0}'." -f $PackageModelResult.InstallDirectory) $PackageModelResult.Install = Install-PackageModelArchive -PackageModelResult $PackageModelResult } 'runInstaller' { Write-PackageModelExecutionMessage -Message ("[ACTION] Running installer into '{0}'." -f $PackageModelResult.InstallDirectory) $installerResult = Invoke-PackageModelInstallerProcess -PackageModelResult $PackageModelResult $PackageModelResult.Install = [pscustomobject]@{ Status = Get-PackageModelOwnedInstallStatus -PackageModelResult $PackageModelResult InstallKind = 'runInstaller' InstallDirectory = $PackageModelResult.InstallDirectory ReusedExisting = $false Installer = $installerResult } } 'packageManagerInstall' { Write-PackageModelExecutionMessage -Message ("[ACTION] Running package-manager install into '{0}'." -f $PackageModelResult.InstallDirectory) $PackageModelResult.Install = Install-PackageModelPackageManagerPackage -PackageModelResult $PackageModelResult } default { throw "Unsupported PackageModel install kind '$($install.kind)'." } } $PackageModelResult.InstallOrigin = 'PackageModelInstalled' Write-PackageModelExecutionMessage -Message ("[ACTION] Completed PackageModel-owned install with status '{0}'." -f $PackageModelResult.Install.Status) return $PackageModelResult } |