Skip to content

Issue #147 #588

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 11, 2024
Merged

Issue #147 #588

merged 6 commits into from
Nov 11, 2024

Conversation

mfortin
Copy link
Contributor

@mfortin mfortin commented Nov 4, 2024

SUMMARY

Attempting to fix Issue #147 as a confirmation is required when it should not.

ISSUE TYPE
  • Bugfix Pull Request
COMPONENT NAME

win_psmodule

ADDITIONAL INFORMATION

Before:

The full traceback is:
Exception calling "ShouldContinue" with "2" argument(s): "A command that prompts the user failed because the host program or the command type does not support user interaction. The host was attempting to request confirmation with the following message: PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\user\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and import the NuGet provider now?"
At line:131 char:13
+             $null = $job | Receive-Job -AutoRemoveJob -Wait -ErrorAct ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-NuGetClientBinaries], MethodInvocationException
    + FullyQualifiedErrorId : HostException,Install-NuGetClientBinaries

at Install-NuGetClientBinaries, C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1: line 7392
at Install-Module, C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1: line 1725
at , : line 26
fatal: [10.0.0.11]: FAILED! => {
    "changed": true,
    "msg": "Problems adding a prerequisite module PackageManagement or PowerShellGet: Exception calling \"ShouldContinue\" with \"2\" argument(s): \"A command that prompts the user failed because the host program or the command type does not support user interaction. The host was attempting to request confirmation with the following message: PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\\Program Files\\PackageManagement\\ProviderAssemblies' or 'C:\\Users\\user\\AppData\\Local\\PackageManagement\\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and import the NuGet provider now?\"",
    "nuget_changed": false,
    "output": "",
    "repository_changed": false
}

After

changed: [10.0.0.11] => {
    "changed": true,
    "nuget_changed": false,
    "output": "Module Microsoft.PowerShell.PSResourceGet installed",
    "repository_changed": false
}

Attempting to fix Issue ansible-collections#147 as a confirmation is required when it should not.
@mfortin mfortin marked this pull request as draft November 4, 2024 15:24
@mfortin mfortin marked this pull request as ready for review November 4, 2024 15:39
@jborean93
Copy link
Collaborator

Thanks for the PR, are you able to create a changelog fragment for this bugfix Thanks for the bugfix, is it possible to add a changelog fragment to document this bugfix https://docs.ansible.com/ansible/latest/community/development_process.html#creating-changelog-fragments.

Just to confirm this fixes a problem when running in check mode and the nuget provider needed to be installed?

@mfortin
Copy link
Contributor Author

mfortin commented Nov 11, 2024

@jborean93 I added the fragment.

The problem also occurs when not running in check mode.
Install-PrereqModule function checks and installs PackageManagement and PowerShellGet. However, it doesn't check if Nuget package provider is installed prior to this installation. If it isn't installed, there is a confirmation dialog that waits for user input to confirm installation of this other dependency. By running Install-NugetProvider as part of the Install-PrereqModule, it no longer is a dependency of another package and can be automatically accepted and installation of the module succeeds.

@jborean93
Copy link
Collaborator

Sorry I misread the change and thought it was just adding -CheckMode. We'll have to move the nuget provider pre-req check and install into the Start-Job below https://github.com/ansible-collections/community.windows/blob/main/plugins/modules/win_psmodule.ps1#L104. Unfortunately we cannot call any PackageManagement or PowerShellGet functions until the actual pre-reqs have been satisfied. If we were to call any PackageManagement function before this we could be inadvertently loading an older version of either package causing problems later on when trying to use the newer one.

Keep in mind the code inside the Start-Job is standalone and won't have access to any of the functions defined in the module.

@mfortin
Copy link
Contributor Author

mfortin commented Nov 11, 2024

I tested it and it works out just fine.

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -WhatIf:$CheckMode | Out-Null
Needs to be done before the Start-Job, or at least before Install-Module PackageManagement.

@jborean93
Copy link
Collaborator

I tested it and it works out just fine.

The issue that goes into more detail for this is #487 but I'll try to explain it again.

It's a complicated scenario that doesn't happen for all scenarios but for some we still need to handle. The problem is using any of the cmdlets from PackageManagement before we've checked to ensure we have our minimum requirement will cause PowerShell to load that older version in the process and we cannot unload or load the newer one. This is ok for some situations but others where Install-Module might pass through extra arguments to PackageManagement during an install and if PackageManagement isn't new enough to understand these parameters it fails. IIRC this was seen with the -AcceptLicense parameter. To compat this we put all the pre-requisite work into a sub-process that we are spawning through Start-Job. Through this we can ensure that PackageManagement and PowerShellGet are installed to the minimums we require when we load it into the main module process.

In the case you are trying to fix, calling Install-PackageProvider before we have ensured PackageManagement is up to date we will load that older version which doesn't support things like -AcceptLicense. We need to do the checks for Install-NugetProvider into the job as well. The simplest solution is to add the following to the top of the job's actions

$nugetProvider = Get-PackageProvider -ListAvailable | Where-Object { ($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201") }
if (-not($nugetProvider)) {
    Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force | Out-Null
}

We don't need to worry about check mode here because the job won't be run in check mode.

Copy link
Collaborator

@jborean93 jborean93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this issue, appreciate the patience while I try to explain the current way the module works.

@jborean93 jborean93 merged commit 27a1530 into ansible-collections:main Nov 11, 2024
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants