Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Failure to download rvm_installer does not fail the resource responsible for installing RVM. #138

Open
wants to merge 1 commit into from

2 participants

Robb Kidd Aaron Kalin
Robb Kidd

Problem

If the curl command for retrieving RVM fails for any reason, the failure errorlevel is swallowed by the pipe to bash.

The execute resource for installing RVM compiled by chef_rvm_recipe_helpers.rb reports success even when curl is unable to download the contents of :installer_url. The original pipe to bash swallows the non-zero errorlevel returned by curl, bash happily runs nothing and returns 0. Errors then appear in subsequent tasks that assume the existence of an installed RVM.

Affects

A particular example are those sad souls who live behind a web proxy that also proxies SSL certs. The curl retrieval will fail because of SSL cert errors. However, anything that prevents the download of the rvm_installer script--e.g. problems with the get.rvm.io domain, bad redirect, invalid certs--will cause this problem.

Signs and Symptoms

Using rvm::system_install

execute[install system-wide RVM] will report having run successfully. On the host, RVM will not be installed in /usr/local/rvm and therefore the rvm command will not be available.

Using rvm::system

Same as rvm::system_install, the install system-wide RVM execute task will report success.

The failure appears in "Processing rvm_default_ruby".

Error executing action `create` on resource 'rvm_default_ruby[ruby-1.9.3-p194]'
============================================================


NoMethodError
-------------
private method `chomp' called for nil:NilClass

Because RVM did not actually install, the RVM scripts used by canonical_ruby_string to determine the default ruby are not present and the chain of methods to determine the version bomb with calling chomp on nil.

Solution

Test that retrieval succeeded before executing.

This pull request has curl write the retrieved script to /tmp, changes the pipe to && which only executes the retrieved script if curl succeeded.

I'm not very proud of writing directly to /tmp. Is there a directory the recipe uses for temporary files needed for execution? Is there call for two execution tasks, one for retrieving rvm_installer and one for executing it upon successful retrieval?

Another option is to retrieve it twice, once to test successful retrieval and, if successful, retrieve it again to pipe it to bash as originally written.

Robb Kidd

My coworker accuses me of gold-plating this 5-line change. Too much?

Aaron Kalin
Collaborator

Hi @robbkidd and thank you for submitting this pull request. Reviewing all the outstanding pull requests and I think yours is well thought out for the small changes. Is this still an issue? Do you know if this problem can be reproduced via test kitchen? I'd like to see if we can merge this change or close it out soon.

Robb Kidd

Looking back on this, I still am not proud of downloading and running from /tmp. Because this is in the context of a chef run, maybe should use Chef::Config[:file_cache_path]? Not sure about replicating the failure in test kitchen. I'll ponder that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 14, 2012
This page is out of date. Refresh to see the latest.
Showing with 1 addition and 4 deletions.
  1. +1 −4 libraries/chef_rvm_recipe_helpers.rb
5 libraries/chef_rvm_recipe_helpers.rb
View
@@ -24,9 +24,6 @@ module RVM
module RecipeHelpers
def build_script_flags(version, branch)
script_flags = ""
- if version || (branch && branch != "none")
- script_flags += " -s --"
- end
if version
script_flags += " --version #{version}"
end
@@ -79,7 +76,7 @@ def install_rvm(opts = {})
i = execute exec_name do
user opts[:user] || "root"
- command "curl -L #{opts[:installer_url]} | bash #{opts[:script_flags]}"
+ command "curl -L #{opts[:installer_url]} -o /tmp/rvm_installer && bash /tmp/rvm_installer #{opts[:script_flags]}"
environment(exec_env)
# excute in compile phase if gem_package recipe is requested
Something went wrong with that request. Please try again.