chocolatey / chocolatey-ansible

The Chocolatey module collection for Ansible
GNU General Public License v3.0
49 stars 30 forks source link

win_chocolately (and other modules) fails with 'Cannot process argument transformation on parameter 'ChocoCommand'' #130

Open gcc42 opened 1 year ago

gcc42 commented 1 year ago

Checklist

What You Are Seeing?

This is on WSL on Windows, an initial install worked as expected, now I did something (possibly upgrade powershell to v5?) which broke win_chocolatey and other chocolatey modules completely. Note that choco install vlc for example on windows still succeeds. I see the same error on, for example, win_chocolatey_facts.

ansible windows  -vvv -i inventory -k -m win_chocolatey -a 'name=vlc state=present'

or

ansible-playbook -vvv -i inventory -k install.yml --tags "vlc"

Inventory just links to the same windows host running WinRM. The above command gives me:

ansible [core 2.15.1]
  config file = None
  configured module search path = ['/home/User/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/User/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/User/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/User/.local/bin/ansible
  python version = 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
No config file found; using defaults
SSH password:
host_list declined parsing /home/User/win/inventory as it did not pass its verify_file() method
script declined parsing /home/User/win/inventory as it did not pass its verify_file() method
auto declined parsing /home/User/win/inventory as it did not pass its verify_file() method
Parsed /home/User/win/inventory inventory source with ini plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
redirecting (type: modules) ansible.builtin.win_chocolatey to chocolatey.chocolatey.win_chocolatey
redirecting (type: modules) ansible.builtin.win_chocolatey to chocolatey.chocolatey.win_chocolatey
Using module file /home/User/.ansible/collections/ansible_collections/chocolatey/chocolatey/plugins/modules/win_chocolatey.ps1
Pipelining is enabled.
<192.168.0.xx> ESTABLISH WINRM CONNECTION FOR USER: User on PORT 5986 TO 192.168.0.xx
EXEC (via pipeline wrapper)
The full traceback is:
Cannot process argument transformation on parameter 'ChocoCommand'. Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Management.Automation.CommandInfo".
At line:131 char:17
+ $chocoCommand = Install-Chocolatey @installParams
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Install-Chocolatey], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Install-Chocolatey

ScriptStackTrace:
at Install-Chocolatey, <No file>: line 1091
at <ScriptBlock>, <No file>: line 131

System.Management.Automation.ParameterBindingArgumentTransformationException: Cannot process argument transformation on parameter 'ChocoCommand'. Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Management.Automation.CommandInfo". ---> System.Management.Automation.ArgumentTransformationMetadataException: Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Management.Automation.CommandInfo". ---> System.Management.Automation.PSInvalidCastException: Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Management.Automation.CommandInfo".
   at System.Management.Automation.LanguagePrimitives.ThrowInvalidCastException(Object valueToConvert, Type resultType)
   at System.Management.Automation.LanguagePrimitives.ConvertNoConversion(Object valueToConvert, Type resultType, Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
   at System.Management.Automation.LanguagePrimitives.ConversionData`1.Invoke(Object valueToConvert, Type resultType, Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
   at System.Management.Automation.LanguagePrimitives.ConvertTo(Object valueToConvert, Type resultType, Boolean recursion, IFormatProvider formatProvider, TypeTable backupTypeTable)
   at System.Management.Automation.ArgumentTypeConverterAttribute.Transform(EngineIntrinsics engineIntrinsics, Object inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet)
   --- End of inner exception stack trace ---
   at System.Management.Automation.ArgumentTypeConverterAttribute.Transform(EngineIntrinsics engineIntrinsics, Object inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet)
   at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
   --- End of inner exception stack trace ---
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
   at System.Management.Automation.PSScriptCmdlet.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
   at System.Management.Automation.PSScriptCmdlet.DoEndProcessing()
   at System.Management.Automation.CommandProcessorBase.Complete()
windows10 | FAILED! => {
    "changed": false,
    "msg": "Unhandled exception while executing module: Cannot process argument transformation on parameter 'ChocoCommand'. Cannot convert the \"System.Object[]\" value of type \"System.Object[]\" to type \"System.Management.Automation.CommandInfo\"."
}

However, if I become_user system, it seems to fix the issue:

ansible windows  -vvv -i inventory -k --become --become-method runas --become-user System -m win_chocolatey -a 'name=filezilla state=present'

outputs:

windows10 | CHANGED => {
    "changed": true,
    "invocation": {
        "module_args": {
            "allow_empty_checksums": false,
            "allow_multiple": false,
            "allow_prerelease": false,
            "architecture":
...
...
"stdout": "Chocolatey v2.0.0\r\nInstalling the following packages:\r\nfilezilla\r\nBy installing, you accept licenses for the packages.\r\n\r\nfilezilla v3.64.0 [Approved]\r\nfilezilla package files install completed. Performing other installation steps.\r\nInstalling 64-bit filezilla...\r\nfilezilla has been installed.\r\n The install of filezilla was successful.\r\n  Software installed as 'exe', install location is likely default.\r\n\r\nChocolatey installed 1/1 packages. \r\n See the log for details (C:\\ProgramData\\chocolatey\\logs\\chocolatey.log).\r\n",
    "stdout_lines": [
        "Chocolatey v2.0.0",
        "Installing the following packages:",
        "filezilla",
        "By installing, you

Either the error message in the first case is highly misleading, or something else fixes the issue when becoming system.

What is Expected?

Expecting the packages to be successfully installed.

How Did You Get This To Happen?

  1. Installed WSL and Ubuntu on Windows
  2. Installed ansible using python3 -m pip install ansible && python3 -m pip install --upgrade ansible
  3. Ran the ansible playbook to install packages on the host
  4. win_ping module works, but win_chocolatey, win_chocolatey_facts etc. shows with the error above

System Details

Installed Packages

Chocolatey v2.0.0
chocolatey 2.0.0
chocolatey-compatibility.extension 1.0.0
chocolatey-core.extension 1.4.0
filezilla 3.64.0
vlc 3.0.18
vlc.install 3.0.18
6 packages installed.

Output Log

Not running Chocolately CLI directly

Additional Context

I tried this for various packages, like notepadplusplus, vlc, filezilla, nirlauncher and same issue. Like I mentioned, I did something that broke a previously working win_chocolatey.

Running Ansible on WSL (Windows Subsystem for Linux) on Windows.

User@Computer:~/win$ ansible --version
ansible [core 2.15.1]
  config file = None
  configured module search path = ['/home/User/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/User/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/User/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/User/.local/bin/ansible
  python version = 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
User@Computer:~/win$ ansible-playbook --version
ansible-playbook [core 2.15.1]
  config file = None
  configured module search path = ['/home/User/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/User/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/User/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/User/.local/bin/ansible-playbook
  python version = 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
mwtrigg commented 1 year ago

I have also encountered this issue in our development environment (still working fine in the production environment).

ansible-playbook [core 2.13.3]
  config file = /runner/project/ansible.cfg
  configured module search path = ['/runner/project/library']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /runner/requirements_collections:/home/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible-playbook
  python version = 3.9.7 (default, Sep 13 2021, 08:18:39) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]
  jinja version = 3.0.3
  libyaml = True

Running this via Ansible Automation Platform

mwtrigg commented 1 year ago

https://github.com/chocolatey/chocolatey-ansible/issues/130#issuecomment-1654243666

Sorted out our issue -- our error was slightly different

Cannot index into a null array.
At line:122 char:17
$chocoCommand = Install-Chocolatey @installParams

Root cause: instead of allowing the win_chocholatey module to bootstrap chocolatey, we wrote a separate poweshell script (much easier to read -- but also because we don't have to deal with older OSes or versions of Powershell) that intalls chocolatey from our own internal repository -- in any event, while chocolatey is installed without incident, it does not actually appear as an installed package. In reviewing the modules code, it looks as if even though the choco binary is present, the fact that its not listed as an installed package leaves all of the expected parameters as undefined.

My quick solution was to simply add a win_powershell task that runs choco.exe install chocolatey --exact --skip-powershell --yes that adds the package without performing additional steps.

ps-klor commented 1 year ago

We are also experiencing this. However, running ansible as become_user does not seem to change anything.

mwtrigg commented 1 year ago

Even after my work arounds, I keep coming back to this line (albeit a slightly different version of the module).

My question - why are we "installing" chocolatey right out of the gate with this module instead of just checking to see if its present? Am I misreading how this module works?

https://github.com/chocolatey/chocolatey-ansible/blob/9bdc0d40437a7dc7f0181af42da7e35bbcfcae4a/chocolatey/plugins/modules/win_chocolatey.ps1#L139

Install-Chocolatey defined: https://github.com/chocolatey/chocolatey-ansible/blob/9bdc0d40437a7dc7f0181af42da7e35bbcfcae4a/chocolatey/plugins/module_utils/Packages.psm1#L1018

JPRuskin commented 1 year ago

Why are we "installing" chocolatey right out of the gate with this module instead of just checking to see if its present?

By my read, the first few lines of Install-Chocolatey are a test to see if the command is present and skip install if it is found. The function, overall, is almost a wrapper for Get-ChocolateyCommand (which does check if it's already present) - but with logic to ensure Chocolatey is present (and/or a greater version than 0.10.5) if not found initially.

    $chocoCommand = Get-ChocolateyCommand -IgnoreMissing
    if ($null -eq $chocoCommand) {
        # We need to install chocolatey
        # ...
    }
    # ...
    $chocoCommand

the fact that its not listed as an installed package leaves all of the expected parameters as undefined.

Root cause: instead of allowing the win_chocholatey module to bootstrap chocolatey, we wrote a separate poweshell script (much easier to read

FWIW, though I've not seen the script you're using, if you end it by copying the Chocolatey nupkg you used to install into the correct folder within the /lib/ directory (as we do at the end of the standard install.ps1) that should solve this. I agree that this is a fun behavioural quirk / workaround.

Write-Host 'Ensuring chocolatey.nupkg is in the lib folder'
$chocoPkgDir = Join-Path $chocoPath -ChildPath 'lib\chocolatey'
$nupkg = Join-Path $chocoPkgDir -ChildPath 'chocolatey.nupkg'
vexx32 commented 3 months ago

The error encountered here actually looks identical to the one from #147, I wonder if these two issues are related in some way.