Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use System.Threading.Mutex to make threadsafe
  • Loading branch information
mikeharder committed Jul 14, 2023
commit c41bd4d22d71f2df931bba4e7587126d7806d1fc
70 changes: 44 additions & 26 deletions eng/common/scripts/Helpers/PSModule-Helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,53 @@ function Install-ModuleIfNotInstalled()

if ($modules.Count -eq 0)
{
$repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl })
if ($repositories.Count -eq 0)
{
Register-PSRepository -Name $repositoryUrl -SourceLocation $repositoryUrl -InstallationPolicy Trusted
$repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl })
if ($repositories.Count -eq 0) {
Write-Error "Failed to registory package repository $repositoryUrl."
return
# Use double-checked locking to avoid locking when module is already installed
$mutex = New-Object System.Threading.Mutex($false, "Install-ModuleIfNotInstalled")
$null = $mutex.WaitOne()

try {
# Check installed modules again after acquiring lock
$modules = (Get-Module -ListAvailable $moduleName)
if ($version -as [Version]) {
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
}
}
$repository = $repositories[0]

if ($repository.InstallationPolicy -ne "Trusted") {
Set-PSRepository -Name $repository.Name -InstallationPolicy "Trusted"
}

Write-Host "Installing module $moduleName with min version $version from $repositoryUrl"
# Install under CurrentUser scope so that the end up under $CurrentUserModulePath for caching
Install-Module $moduleName -MinimumVersion $version -Repository $repository.Name -Scope CurrentUser -Force

# Ensure module installed
$modules = (Get-Module -ListAvailable $moduleName)
if ($version -as [Version]) {
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
if ($modules.Count -eq 0)
{
$repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl })
if ($repositories.Count -eq 0)
{
Register-PSRepository -Name $repositoryUrl -SourceLocation $repositoryUrl -InstallationPolicy Trusted
$repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl })
if ($repositories.Count -eq 0) {
Write-Error "Failed to register package repository $repositoryUrl."
return
}
}
$repository = $repositories[0]

if ($repository.InstallationPolicy -ne "Trusted") {
Set-PSRepository -Name $repository.Name -InstallationPolicy "Trusted"
}

Write-Host "Installing module $moduleName with min version $version from $repositoryUrl"
# Install under CurrentUser scope so that the end up under $CurrentUserModulePath for caching
Install-Module $moduleName -MinimumVersion $version -Repository $repository.Name -Scope CurrentUser -Force

# Ensure module installed
$modules = (Get-Module -ListAvailable $moduleName)
if ($version -as [Version]) {
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
}

if ($modules.Count -eq 0) {
Write-Error "Failed to install module $moduleName with version $version"
return
}
}
}

if ($modules.Count -eq 0) {
Write-Error "Failed to install module $moduleName with version $version"
return
finally {
$mutex.ReleaseMutex()
}
}

Expand Down