Support/Package/Lifecycle/Eigenverft.Manifested.Package.Package.Install.ps1
|
<#
Eigenverft.Manifested.Package.Package.Install Set-PackageAssignedState orchestration only. Fragment scripts are dot-sourced from Eigenverft.Manifested.Package.psm1 (and Eigenverft.Manifested.Package.TestImports.ps1) in dependency order immediately before this file. #> function Stage-PackageArtifactFilesForInstallation { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageResult ) if (@($PackageResult.ArtifactFiles).Count -eq 0) { return $PackageResult } if (-not $PackageResult.ArtifactPreparation -or -not [bool]$PackageResult.ArtifactPreparation.Success) { throw "Installation for '$($PackageResult.PackageId)' requires the complete verified artifact file set." } $artifactInstallStageDirectory = Resolve-PackageArtifactChildPath -RootPath ([string]$PackageResult.PackageInstallStageDirectory) -RelativePath 'Artifacts' Remove-PathIfExists -Path $PackageResult.PackageInstallStageDirectory | Out-Null $null = New-Item -ItemType Directory -Path $artifactInstallStageDirectory -Force foreach ($artifactFile in @($PackageResult.ArtifactFiles)) { if (-not (Test-Path -LiteralPath $artifactFile.StagingPath -PathType Leaf)) { throw "Required artifact file '$($artifactFile.Id)' is missing from staging." } $targetPath = Resolve-PackageArtifactChildPath -RootPath $artifactInstallStageDirectory -RelativePath ([string]$artifactFile.RelativePath) -ArtifactFileId ([string]$artifactFile.Id) $null = New-Item -ItemType Directory -Path (Split-Path -Parent $targetPath) -Force $null = Copy-FileToPath -SourcePath ([string]$artifactFile.StagingPath) -TargetPath $targetPath -Overwrite } $install = Get-PackageAssignedInstallOperation -Release $PackageResult.Package if ($install -and $install.PSObject.Properties['artifactFileId']) { $PackageResult.OperationArtifactFile = Get-PackageArtifactFileResult -PackageResult $PackageResult -ArtifactFileId ([string]$install.artifactFileId) $PackageResult.OperationArtifactFilePath = Resolve-PackageArtifactChildPath -RootPath $artifactInstallStageDirectory -RelativePath ([string]$PackageResult.OperationArtifactFile.RelativePath) -ArtifactFileId ([string]$PackageResult.OperationArtifactFile.Id) } $PackageResult | Add-Member -MemberType NoteProperty -Name InstallArtifactStagingDirectory -Value $artifactInstallStageDirectory -Force Write-PackageExecutionMessage -Message ("[STATE] Staged {0} artifact file(s) for installation under '{1}'." -f @($PackageResult.ArtifactFiles).Count, $artifactInstallStageDirectory) return $PackageResult } function Set-PackageAssignedState { <# .SYNOPSIS Assigns the selected package using packageOperations.assigned.install. .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 assigned-state result to the Package result object. .PARAMETER PackageResult The Package result object to enrich. .EXAMPLE Set-PackageAssignedState -PackageResult $result #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [psobject]$PackageResult ) $package = $PackageResult.Package $install = Get-PackageAssignedInstallOperation -Release $package if (-not $install -or -not $install.PSObject.Properties['kind']) { throw "Package release '$($package.id)' does not define packageOperations.assigned.install.kind." } if ([string]::Equals([string]$PackageResult.InstallOrigin, 'AlreadySatisfied', [System.StringComparison]::OrdinalIgnoreCase)) { Write-PackageExecutionMessage -Message "[ACTION] Skipped installer because machine prerequisite is already satisfied." return $PackageResult } if ($PackageResult.ExistingPackage -and $PackageResult.ExistingPackage.Decision -eq 'ReusePackageOwned') { $PackageResult.InstallDirectory = $PackageResult.ExistingPackage.InstallDirectory $PackageResult.InstallOrigin = 'PackageReused' $PackageResult.Assigned = [pscustomobject]@{ Status = 'ReusedPackageOwned' InstallKind = 'existingInstall' InstallDirectory = $PackageResult.ExistingPackage.InstallDirectory ReusedExisting = $true CandidatePath = $PackageResult.ExistingPackage.CandidatePath } $PackageResult.Readiness = $PackageResult.ExistingPackage.Readiness Write-PackageExecutionMessage -Message ("[ACTION] Reused Package-owned install '{0}'." -f $PackageResult.ExistingPackage.InstallDirectory) return $PackageResult } if ($PackageResult.ExistingPackage -and $PackageResult.ExistingPackage.Decision -eq 'AdoptExternal' -and [string]::Equals([string]$install.kind, 'powershellModuleInstaller', [System.StringComparison]::OrdinalIgnoreCase)) { $moduleStatus = if ($PackageResult.ExistingPackage.PSObject.Properties['DiscoveryDetails']) { $PackageResult.ExistingPackage.DiscoveryDetails } else { $null } $PackageResult.InstallDirectory = $null $PackageResult.InstallOrigin = 'AdoptedExternal' $PackageResult.Assigned = [pscustomobject]@{ Status = 'AdoptedExternal' InstallKind = 'powershellModuleInstaller' TargetKind = 'powershellModule' InstallDirectory = $null ReusedExisting = $true CandidatePath = $PackageResult.ExistingPackage.CandidatePath ModuleName = if ($moduleStatus -and $moduleStatus.PSObject.Properties['moduleName']) { [string]$moduleStatus.moduleName } else { [string]$install.moduleName } RequiredVersion = if ($moduleStatus -and $moduleStatus.PSObject.Properties['requiredVersion']) { [string]$moduleStatus.requiredVersion } else { [string]$install.requiredVersion } InstalledVersion = if ($moduleStatus -and $moduleStatus.PSObject.Properties['installedVersion']) { [string]$moduleStatus.installedVersion } else { $null } ModuleBase = if ($moduleStatus -and $moduleStatus.PSObject.Properties['moduleBase']) { [string]$moduleStatus.moduleBase } else { $PackageResult.ExistingPackage.CandidatePath } Scope = if ($moduleStatus -and $moduleStatus.PSObject.Properties['scope']) { [string]$moduleStatus.scope } else { if ($install.PSObject.Properties['scope']) { [string]$install.scope } else { 'CurrentUser' } } OperationArtifactFilePath = $PackageResult.OperationArtifactFilePath } $PackageResult.Readiness = $PackageResult.ExistingPackage.Readiness Write-PackageExecutionMessage -Message ("[ACTION] Adopted external PowerShell module '{0}' version '{1}'." -f [string]$PackageResult.Assigned.ModuleName, [string]$PackageResult.Assigned.RequiredVersion) return $PackageResult } if ($PackageResult.ExistingPackage -and $PackageResult.ExistingPackage.Decision -eq 'AdoptExternal') { $PackageResult.InstallDirectory = $PackageResult.ExistingPackage.InstallDirectory $PackageResult.InstallOrigin = 'AdoptedExternal' $PackageResult.Assigned = [pscustomobject]@{ Status = 'AdoptedExternal' InstallKind = 'existingInstall' InstallDirectory = $PackageResult.ExistingPackage.InstallDirectory ReusedExisting = $true CandidatePath = $PackageResult.ExistingPackage.CandidatePath } $PackageResult.Readiness = $PackageResult.ExistingPackage.Readiness Write-PackageExecutionMessage -Message ("[ACTION] Adopted external install '{0}'." -f $PackageResult.ExistingPackage.InstallDirectory) return $PackageResult } if ([string]::Equals([string]$install.kind, 'reuseExisting', [System.StringComparison]::OrdinalIgnoreCase)) { throw "Package release '$($package.id)' requires an existing install, but no reusable install passed readiness." } if ($PackageResult.ArtifactPreparation -and -not $PackageResult.ArtifactPreparation.Success) { throw 'One or more required artifact files could not be prepared.' } $PackageResult = Stage-PackageArtifactFilesForInstallation -PackageResult $PackageResult switch -Exact ([string]$install.kind) { 'expandArchive' { Write-PackageExecutionMessage -Message ("[ACTION] Assigning package archive into '{0}'." -f $PackageResult.InstallDirectory) $PackageResult.Assigned = Install-PackageArchive -PackageResult $PackageResult } 'placePackageFile' { Write-PackageExecutionMessage -Message ("[ACTION] Placing package file into '{0}'." -f $PackageResult.InstallDirectory) $PackageResult.Assigned = Install-PackagePackageFile -PackageResult $PackageResult } 'runInstaller' { $targetKind = Get-PackageInstallTargetKind -Package $package $targetText = if ([string]::IsNullOrWhiteSpace([string]$PackageResult.InstallDirectory)) { '<machine prerequisite>' } else { [string]$PackageResult.InstallDirectory } Write-PackageExecutionMessage -Message ("[ACTION] Running installer for target '{0}'." -f $targetText) $installerResult = Invoke-PackageInstallerProcess -PackageResult $PackageResult $PackageResult.Assigned = [pscustomobject]@{ Status = Get-PackageOwnedInstallStatus -PackageResult $PackageResult InstallKind = 'runInstaller' TargetKind = $targetKind InstallDirectory = $PackageResult.InstallDirectory ReusedExisting = $false Installer = $installerResult } } 'nsisInstaller' { Write-PackageExecutionMessage -Message ("[ACTION] Running NSIS installer for target '{0}'." -f $PackageResult.InstallDirectory) $installerResult = Invoke-PackageNsisInstallerProcess -PackageResult $PackageResult $PackageResult.Assigned = [pscustomobject]@{ Status = Get-PackageOwnedInstallStatus -PackageResult $PackageResult InstallKind = 'nsisInstaller' TargetKind = Get-PackageInstallTargetKind -Package $package InstallDirectory = $PackageResult.InstallDirectory ReusedExisting = $false Installer = $installerResult } } 'innoSetupInstaller' { Write-PackageExecutionMessage -Message ("[ACTION] Running Inno Setup installer for target '{0}'." -f $PackageResult.InstallDirectory) $installerResult = Invoke-PackageInnoSetupInstallerProcess -PackageResult $PackageResult $PackageResult.Assigned = [pscustomobject]@{ Status = Get-PackageOwnedInstallStatus -PackageResult $PackageResult InstallKind = 'innoSetupInstaller' TargetKind = Get-PackageInstallTargetKind -Package $package InstallDirectory = $PackageResult.InstallDirectory ReusedExisting = $false Installer = $installerResult } } 'msiInstaller' { Write-PackageExecutionMessage -Message ("[ACTION] Running MSI installer for target '{0}'." -f $PackageResult.InstallDirectory) $installerResult = Invoke-PackageMsiInstallerProcess -PackageResult $PackageResult $PackageResult.Assigned = [pscustomobject]@{ Status = Get-PackageOwnedInstallStatus -PackageResult $PackageResult InstallKind = 'msiInstaller' TargetKind = Get-PackageInstallTargetKind -Package $package InstallDirectory = $PackageResult.InstallDirectory ReusedExisting = $false Installer = $installerResult } } 'npmMaterializedInstallGlobalPackage' { Write-PackageExecutionMessage -Message ("[ACTION] Installing materialized npm global package into '{0}'." -f $PackageResult.InstallDirectory) $PackageResult.Assigned = Install-PackageNpmMaterializedInstallGlobalPackage -PackageResult $PackageResult } 'powershellModuleInstaller' { Write-PackageExecutionMessage -Message ("[ACTION] Installing PowerShell module '{0}' from staged package file." -f [string]$install.moduleName) $PackageResult.Assigned = Install-PackagePowerShellModule -PackageResult $PackageResult } default { throw "Unsupported packageOperations.assigned.install.kind '$($install.kind)'." } } $PackageResult.InstallOrigin = if ([string]::Equals((Get-PackageInstallTargetKind -Package $package), 'machinePrerequisite', [System.StringComparison]::OrdinalIgnoreCase)) { 'PackageApplied' } elseif ([string]::Equals([string]$install.kind, 'powershellModuleInstaller', [System.StringComparison]::OrdinalIgnoreCase)) { 'PackageApplied' } else { 'PackageInstalled' } Write-PackageExecutionMessage -Message ("[ACTION] Completed Package assign with status '{0}'." -f $PackageResult.Assigned.Status) return $PackageResult } |