Skip to content
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

win_chocolatey: ChocolateyInstall.ps1 from Internal Repositories fails (Sonatype Nexus) #18

Closed
adilio opened this issue Jun 10, 2020 · 11 comments · Fixed by #38
Closed
Labels
Improvement Issues that enhances existing functionality, or adds new features
Milestone

Comments

@adilio
Copy link
Contributor

adilio commented Jun 10, 2020

  • Ansible Version: 2.9
  • Chocolatey Module Version: ??

Myself and @steviecoaster have just worked through this with a customer setting up C4B and an organizational installation hosted on Sonatype Nexus. The "raw" repository hosting the offline install script for Chocolatey itself is at a URL similar to:
http://localhost:8081/repository/choco-install/install.ps1

The win_chocolatey module uses the Chocolatey (Simple) Server approach of only looking in the root URL for an install.ps1 script. This is not the pattern in other repository management applications like Sonatype Nexus or JFrog Artifactory.

We need to build some conditional logic into this statement, to handle these additional use cases for our C4B customers:

if ($source) {
# check if the URL already contains the path to PS script
if ($source.EndsWith(".ps1")) {
$script_url = $source
} else {
# chocolatey server automatically serves a script at
# http://host/install.ps1, we rely on this behaviour when a
# user specifies the choco source URL. If a custom URL or file
# path is desired, they should use win_get_url/win_shell
# manually
# we need to strip the path off the URL and append install.ps1
$uri_info = [System.Uri]$source
$script_url = "$($uri_info.Scheme)://$($uri_info.Authority)/install.ps1"
}

@adilio adilio changed the title win_chocolatey: ChocolateyInstall.ps1 from Internal Repositories fails (Sonatype Nexus) win_chocolatey: ChocolateyInstall.ps1 from Internal Repositories fails (Sonatype Nexus) Jun 10, 2020
@vexx32 vexx32 added the Improvement Issues that enhances existing functionality, or adds new features label Jun 10, 2020
@ferventcoder
Copy link
Member

I know that we have folks use a different url for this - https://chocolatey.org/install#ansible

if ($source) {
# check if the URL already contains the path to PS script
if ($source.EndsWith(".ps1")) {
$script_url = $source
} else {
# chocolatey server automatically serves a script at
# http://host/install.ps1, we rely on this behaviour when a
# user specifies the choco source URL. If a custom URL or file
# path is desired, they should use win_get_url/win_shell
# manually
# we need to strip the path off the URL and append install.ps1
$uri_info = [System.Uri]$source
$script_url = "$($uri_info.Scheme)://$($uri_info.Authority)/install.ps1"
}

If you pass the full source being to the URL it should use that as seen at https://chocolatey.org/install#ansible:

- name: Ensure Chocolatey installed from internal repo
  win_chocolatey:
    name: chocolatey
    state: present
    source: http://script/url/from/generic/tab/ChocolateyInstall.ps1

@ferventcoder
Copy link
Member

Line 252/253 there are what I'm mentioning.

@ferventcoder
Copy link
Member

ferventcoder commented Jun 10, 2020

This could be ciphers? If things are set with higher ciphers (say TLS 1.1/1.2) and older ones are turned off - jumping to PowerShell isn't going to allow this to work unless the PowerShell opts in to the higher ciphers.

Nevermind -

# Enable TLS1.1/TLS1.2 if they're available but disabled (eg. .NET 4.5)
$security_protocols = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::SystemDefault
if ([Net.SecurityProtocolType].GetMember("Tls11").Count -gt 0) {
$security_protocols = $security_protcols -bor [Net.SecurityProtocolType]::Tls11
}
if ([Net.SecurityProtocolType].GetMember("Tls12").Count -gt 0) {
$security_protocols = $security_protcols -bor [Net.SecurityProtocolType]::Tls12
}
[Net.ServicePointManager]::SecurityProtocol = $security_protocols

@vexx32
Copy link
Member

vexx32 commented Jun 10, 2020

Yeah, explicit/direct file URL would be best. I don't see anything necessarily wrong with attempting a few common patterns if we just have the base url though.

@steviecoaster
Copy link
Collaborator

The issue stems from us seeing this fall over in person where a direct URL to a ps1 file fell over and returned the base url appended by Install.ps1 So for some reason, it doesn't appear to be hitting that code path and doing the right thing.

@vexx32
Copy link
Member

vexx32 commented Jun 10, 2020

If I had to guess, I'd guess that $source.EndsWith(".ps1") is case sensitive for that extension. That definitely needs to be changed to either a -match which won't be case sensitive, or just use an overload which prevents case sensitivity.

@jborean93
Copy link
Contributor

jborean93 commented Jun 11, 2020

If someone had a task

- win_chocolatey:
    name: chocolatey
    state: present
    source: http://script/url/from/generic/tab/ChocolateyInstall.ps1

Then it should be using that URL to get that script and install Chocolatey. The workflow of bootstrapping code followed this process

  • If source is not defined use https://chocolatey.org/install.ps1
  • If source ends with .ps1 then use that directly to download the script and install
  • Else get the scheme and authority and append /install.ps1 and use that to bootstrap Chocolatey - this is meant to work with Chocolatey simple server

So the scenario that was given by @adilio should work right now without any changes.

@ferventcoder
Copy link
Member

Just for more clarity, this ends failing on

if ($null -eq $choco_app -or -not (Test-Path -LiteralPath $choco_app.Path)) {
$module.FailJson("Failed to find choco.exe, make sure it is added to the PATH or the env var 'ChocolateyInstall' is set")
}
.

@ferventcoder
Copy link
Member

We are watching this miss the section on installation at

if (-not $module.CheckMode) {
$res = Run-Command -command "powershell.exe -" -stdin $install_script -environment $environment
if ($res.rc -ne 0) {
$module.Result.rc = $res.rc
$module.Result.stdout = $res.stdout
$module.Result.stderr = $res.stderr
$module.FailJson("Chocolatey bootstrap installation failed.")
}
$module.Warn("Chocolatey was missing from this system, so it was installed during this task run.")
}
$module.Result.changed = $true

Check mode is not on, but it never runs this section. It's kind of perplexing on our end, hopefully we'll have more details on this soon.

@jborean93
Copy link
Contributor

This is definitely a weird one based on the output shared we can see that "changed": true is set but no warning message is shown on the output so the Run-Command block isn't running at all. Based on the verbose output there's no indication that check mode has been set and even if it was it would be showing as skipped with https://github.com/ansible/ansible/blob/v2.9.9/lib/ansible/modules/windows/win_chocolatey.ps1#L295-L299.

You can set ANSIBLE_KEEP_REMOTE_FILES=true as an env var and Ansible will place the powershell payload in the user's temp dir (folder can be configured) that is run for a module on the file system and will not delete the file when it's finished. You can then inspect this payload to see the exact options that Ansible sends to the module. Keep in mind this may contain sensitive data so it should only ever be set for debugging purposes.

@adilio
Copy link
Contributor Author

adilio commented Apr 13, 2021

I have since tested this install method, @vexx32, and can confirm it now works as expected. I'll go ahead and close this issue.

Appreciate your efforts!

@adilio adilio closed this as completed Apr 13, 2021
vexx32 added a commit that referenced this issue May 5, 2021
…all script URL (#38)

* 🐛 (#18) Use case-insensitive check for *.ps1

* ✨ (#18) Improve install source url handling

* ♻️ Update chocolatey/plugins/modules/win_chocolatey.ps1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Improvement Issues that enhances existing functionality, or adds new features
Projects
None yet
5 participants