ansible-collections / ansible.windows

Windows core collection for Ansible
https://galaxy.ansible.com/ansible/windows
GNU General Public License v3.0
232 stars 157 forks source link

win_package doesn't work with https URL to msixbundle #503

Open m-khvoinitsky opened 1 year ago

m-khvoinitsky commented 1 year ago
SUMMARY

win_package doesn't work with https URL to msixbundle, only local URLs work

ISSUE TYPE
COMPONENT NAME

win_package

ANSIBLE VERSION
ansible [core 2.14.5]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.11/site-packages/ansible
  ansible collection location = ~/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.11.3 (main, Apr  5 2023, 15:52:25) [GCC 12.2.1 20230201] (/usr/bin/python)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
# /usr/lib/python3.11/site-packages/ansible_collections
Collection      Version
--------------- -------
ansible.windows 1.13.0
OS / ENVIRONMENT

Controller OS: archlinux Target OS: Windows 10

STEPS TO REPRODUCE
This doesn't work:
  - name: Windows Terminal
    ansible.windows.win_package:
      path: 'https://github.com/microsoft/terminal/releases/download/v1.16.10261.0/Microsoft.WindowsTerminal_Win10_1.16.10261.0_8wekyb3d8bbwe.msixbundle'
      state: present
The full traceback is:
Exception calling "CreateProcess" with "7" argument(s): "CreateProcessW() failed (The system cannot find the file specified, Win32ErrorCode 2 - 0x00000002)"
At line:678 char:15
+     $result = Start-AnsibleWindowsProcess @commandArgs
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Start-AnsibleWindowsProcess], MethodInvocationException
    + FullyQualifiedErrorId : Win32Exception,Start-AnsibleWindowsProcess

ScriptStackTrace:
at Start-AnsibleWindowsProcess, <No file>: line 230
at Invoke-Executable, <No file>: line 678
at <ScriptBlock>, <No file>: line 1327
at <ScriptBlock>, <No file>: line 1479

System.Management.Automation.MethodInvocationException: Exception calling "CreateProcess" with "7" argument(s): "CreateProcessW() failed (The system cannot find the file specified, Win32ErrorCode 2 - 0x00000002)" ---> ansible_collections.ansible.windows.plugins.module_utils.Process.Win32Exception: CreateProcessW() failed (The system cannot find the file specified, Win32ErrorCode 2 - 0x00000002)
   at ansible_collections.ansible.windows.plugins.module_utils.Process.ProcessUtil.NativeCreateProcess(String applicationName, String commandLine, SecurityAttributes processAttributes, SecurityAttributes threadAttributes, Boolean inheritHandles, ProcessCreationFlags creationFlags, IDictionary environment, String currentDirectory, StartupInfo startupInfo) in c:\Users\job-ms1_i12e\AppData\Local\Temp\wwuzwcc4.2.cs:line 440
   at ansible_collections.ansible.windows.plugins.module_utils.Process.ProcessUtil.CreateProcess(String lpApplicationName, String lpCommandLine, String lpCurrentDirectory, IDictionary environment, Byte[] stdin, String outputEncoding, Boolean waitChildren) in c:\Users\job-ms1_i12e\AppData\Local\Temp\wwuzwcc4.2.cs:line 404
   at CallSite.Target(Closure , CallSite , Type , Object , String , String , Object , Object , String , SwitchParameter )
   --- 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()
fatal: [lt1-bawin-27]: FAILED! => changed=false
  msg: 'Unhandled exception while executing module: Exception calling "CreateProcess" with "7" argument(s): "CreateProcessW() failed (The system cannot find the file specified, Win32ErrorCode 2 - 0x00000002)"'
This works:
  - name: Download Windows Terminal
    ansible.windows.win_get_url:
      url: 'https://github.com/microsoft/terminal/releases/download/v1.16.10261.0/Microsoft.WindowsTerminal_Win10_1.16.10261.0_8wekyb3d8bbwe.msixbundle'
      dest: 'C:/'
    register: get_url_winterminal
  - name: Windows Terminal
    ansible.windows.win_package:
      path: '{{ get_url_winterminal.dest }}'
      state: present
robinmalik commented 8 months ago

I hit this also, trying to install Git from https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/Git-2.42.0.2-64-bit.exe

robinmalik commented 8 months ago

FWIW, I switch the source to a different domain over https, and it worked. I seem to recall having some problem in the past relating to getting files from Github. It wasn't within Ansible but I believe the underlying problem was redirection handling.

Does this help you, @m-khvoinitsky : https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_package_module.html#parameter-follow_redirects

m-khvoinitsky commented 8 months ago

FWIW, I switch the source to a different domain over https, and it worked. I seem to recall having some problem in the past relating to getting files from Github. It wasn't within Ansible but I believe the underlying problem was redirection handling.

Does this help you, @m-khvoinitsky : https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_package_module.html#parameter-follow_redirects

At the moment I can't verify as currently the related code is a bit different. But it seems unlikely since doc says:

follow_redirects: "safe" ← (default), safe will follow only “safe” redirects, where “safe” means that the client is only doing a GET or HEAD on the URI to which it is being redirected.

I don't think that downloading a file requires something different than GET request.

robinmalik commented 8 months ago

Yeah, confirmed it doesn't work for me sadly (whether safe/all).

samueln-w commented 1 month ago

This is likely related to the format of the resultant links that Git provides from the redirect. For instance, this URL:

https://github.com/git-for-windows/git/releases/download/v2.35.1.windows.2/Git-2.35.1.2-64-bit.exe

...returns a 302 redirect that seems to change over time. The URL I was redirected to yesterday (that worked just fine then) returns a 401 today. But, the redirect takes the general form of:

https://objects.githubusercontent.com/github-production-release-asset-2e65be/23216272/ec06f3ce-e1e7-4785-9ca4-84b7efb3a906?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=releaseassetproduction%2F<YYYYMMDD>%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=<YYYYMMDD>T<HHMMSS>Z&X-Amz-Expires=300&X-Amz-Signature=<big hex string>&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=23216272&response-content-disposition=attachment%3B%20filename%3DGit-2.35.1.2-64-bit.exe&response-content-type=application%2Foctet-stream

Notably, the redirected URL doesn't end with .exe (with or without GET parameters). I'm not sure how to check this, but I wonder whether win_package is downloading the file with a strange name such as ec06f3ce-e1e7-4785-9ca4-84b7efb3a906. Or, given CreateProcess's claim that it can't find the file to start, perhaps win_package gets so confused by the redirected URL it fails to download any file at all.

Whatever the case, there are 3 reasonable ways I see for win_package to get a usable filename in this situation:

  1. The redirected URL provides the Content-Disposition header with the value attachment; filename=Git-2.35.1.2-64-bit.exe. This probably should be checked for all downloads, even those where the filename provided by the URL seems reasonable.
  2. The URL provided to win_package could be checked. In (some? most?) cases, this should provide at least the correct extension, which is (probably) all that really matters.
  3. An extension or filename parameter could be added to win_package.