rvm / rvm1-ansible

The official ansible RVM role to install and manage your Ruby versions.
MIT License
271 stars 136 forks source link

rvm not found? #88

Open jrodrigosm opened 8 years ago

jrodrigosm commented 8 years ago

Hi,

I'm finding a strange behaviour after installing rvm: the rvm command is not found.

I am running the following playbook to install rvm, install a couple of ruby versions, and, after installation, check that rvm has been installed by printing the rvm version:


---
- hosts: test
  become: yes

  pre_tasks:
    - name: Ensure curl is installed
      package: name=curl state=present

  roles:
    - role: rvm_io.rvm1-ruby
      rvm1_rubies:
        - ruby-2.2.1
        - ruby-2.3.0

  tasks:
    - name: show rvm version for regular user
      command: rvm -v
      become: no
      register: rvm_version
    - debug: var=rvm_version.stdout

    - name: show rvm version for root
      command: rvm -v
      register: rvm_version
    - debug: var=rvm_version.stdout

The installation goes smoothly, but I get an error when running the rvm command:

TASK [show rvm version for regular user] ***************************************
fatal: [test]: FAILED! => {"changed": false, "cmd": "rvm -v", "failed": true, "msg": "[Errno 2] No such file or directory", "rc": 2}

I thought the issue could be that I was using the "command" module to run rvm. I then switched to the "shell" module but I still get an error:

TASK [show rvm version for regular user] ***************************************
fatal: [test]: FAILED! => {"changed": true, "cmd": "rvm -v", "delta": "0:00:00.005780", "end": "2016-03-23 19:28:38.176382", "failed": true, "rc": 127, "start": "2016-03-23 19:28:38.170602", "stderr": "/bin/sh: 1: rvm: not found", "stdout": "", "stdout_lines": [], "warnings": []}

Any ideas? Why could this be happening?

(If you wonder about my use case: I want to run a play to change the ruby version; as such, I want to run command: rvm use 2.2.1 - but I can't, because rvm is not found)

I'm running the playbook with ansible 2.0.1.0, rvm_io.rvm1-ruby v1.3.7 and both machines (control and target) are running Debian 8.

hut8 commented 8 years ago

You're using /bin/sh with the shell module. It behaves differently than bash which you are likely using interactively, including in which initialization files it runs. Also, with any shells (AFAIK), interactive and noninteractive shells run different initialization scripts as well. So in general this is not exactly a simple problem! Moreover, you're heading down a dead end.

If you were to use rvm use ..., and actually get it to work, then RVM would set everything up in that instance of the shell -- in other words, for that one process. Then the shell exits, and everything is back to how it was. You can see if you use ansible-playbook -vvvv how very separate each play is!

jrodrigosm commented 8 years ago

I see ... This would rule out calling "rvm use" directly from the playbook. Maybe anyone would have any pointers on accomplishing the following in just a single run of a playbook (I don't want to have to call the playbook twice)?:

If you were to use rvm use ..., and actually get it to work, then RVM would set everything up in that instance of the shell -- in other words, for that one process. Then the shell exits, and everything is back to how it was. You can see if you use ansible-playbook -vvvv how very separate each play is!

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub

hut8 commented 8 years ago

I use Capistrano and Ansible. As you know, they're separate tools, but naturally they work together. Personally, I would completely separate upgrading Ruby from rolling out the new version of your application. I would modify your Ansible script first to install the new Ruby version:

rvm1_rubies:
  - 'ruby-2.1.3'
  - 'ruby-2.3.0'

That sets the last one as the default. You may want to be more explicit about this. I have my Passenger configured to use /usr/local/bin/ruby which is where the system-wide RVM "installs ruby"... but it's really just a symlink to a script:

liam@machine ~ [ruby-2.2.3p173] % which ruby                                                                                               
/usr/local/bin/ruby
liam@machine ~ [ruby-2.2.3p173] % file $(which ruby)
/usr/local/bin/ruby: symbolic link to `/usr/local/rvm/wrappers/default/ruby'
liam@rails-assets ~ [ruby-2.2.3p173] % cat /usr/local/rvm/wrappers/default/ruby
#!/usr/bin/env bash

if
  [[ -s "/usr/local/rvm/gems/ruby-2.2.3/environment" ]]
then
  source "/usr/local/rvm/gems/ruby-2.2.3/environment"
  exec ruby "$@"
else
  echo "ERROR: Missing RVM environment file: '/usr/local/rvm/gems/ruby-2.2.3/environment'" >&2
  exit 1
fi

The existing workers in memory will use the "old" version of Ruby. You didn't mention which application server you use, but I usually use Passenger (currently I'm using 5). In the configuration (it's actually in nginx.conf), I have it pointed at the file above (/usr/local/bin/ruby). By restarting the app server, now suddenly they're all on the new version of Ruby, assuming I installed the new version as the default.

Thoughts?

jrodrigosm commented 8 years ago

The key is your point about the existing workers using the previous version until you restart the app server. I had not thought about that. That will work for me, it will minimize downtime. I'm not using passenger but puma (with the puma jungle) so I need to do some research on my own to make sure that puma behaves in the way that you described, but this seems the way to go. Thanks for your help. Feel free to close the issue, and I will update it, for reference, with my puma config once I have solved it from my side.

On Mon, Mar 28, 2016 at 6:16 PM, Liamnotifications@github.com wrote:
I use Capistrano and Ansible. As you know, they're separate tools, but naturally they work together. Personally, I would completely separate upgrading Ruby from rolling out the new version of your application. I would modify your Ansible script first to install the new Ruby version: rvm1_rubies:

That sets the last one as the default. You may want to be more explicit about this. I have my Passenger configured to use /usr/local/bin/ruby which is where the system-wide RVM "installs ruby"... but it's really just a symlink to a script: liam@machine ~ [ruby-2.2.3p173] % which ruby
/usr/local/bin/ruby liam@machine ~ [ruby-2.2.3p173] % file $(which ruby) /usr/local/bin/ruby: symbolic link to `/usr/local/rvm/wrappers/default/ruby' liam@rails-assets ~ [ruby-2.2.3p173] % cat /usr/local/rvm/wrappers/default/ruby

!/usr/bin/env bash

if [[ -s "/usr/local/rvm/gems/ruby-2.2.3/environment" ]] then source "/usr/local/rvm/gems/ruby-2.2.3/environment" exec ruby "$@" else echo "ERROR: Missing RVM environment file: '/usr/local/rvm/gems/ruby-2.2.3/environment'" >&2 exit 1 fi

The existing workers in memory will use the "old" version of Ruby. You didn't mention which application server you use, but I usually use Passenger (currently I'm using 5). In the configuration (it's actually in nginx.conf), I have it pointed at the file above (/usr/local/bin/ruby). By restarting the app server, now suddenly they're all on the new version of Ruby, assuming I installed the new version as the default.

Thoughts?

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub

lpaulmp commented 8 years ago

@jrodrigosm Did you fix this issue?

iteratelance commented 8 years ago

I've run into the same issue and gotten around the problem by explicitly running the bash command for rvm commands. I suppose you could also use the full path to rvm but I think that the following is a better option.

- name: Set ruby default
  shell: 'bash -lc "rvm use 2.3.1 --default"'