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

improve command map combined with prefix #311

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

mikz
Copy link
Contributor

@mikz mikz commented Dec 28, 2015

It is valid use case to set both command map and prefix.
In case of using different binary, the map should still be active and prefixed.

Includes and closes #310.

Will squash the commits when we agree that it makes sense.

It changes prefix to generate: bundle exec /usr/bin/env rake instead of bundle exec rake.
Would that be a breaking change?

@mikz mikz force-pushed the improve-command-map-prefixes branch 3 times, most recently from b530fbf to 1d95fcd Compare December 29, 2015 10:25
@mattbrictson
Copy link
Member

I think this could break capistrano-rbenv. It adds the prefix $HOME/.rbenv/bin/rbenv exec, and this would happen:

$HOME/.rbenv/bin/rbenv exec /usr/bin/env rake
rbenv: /usr/bin/env: command not found

@mikz
Copy link
Contributor Author

mikz commented Dec 30, 2015

@mattbrictson will check, thanks!

I'd expect rbenv exec to behave like bundle exec. Running any executable file with different environment. https://github.com/rbenv/rbenv/blob/a95ccd09a2c7cff435d915756abd5a2fe096fb9d/libexec/rbenv-exec looks like does exactly that, just prepares environment and calls exec.

I think running anything in /usr/bin/env should be harmless.

@leehambley
Copy link
Member

So did we think we would merge this? This would also solve #299 which I'd be glad of, reading the notes here from you both it looks like the rbenv issue was not really an issue?

@mattbrictson
Copy link
Member

I believe rbenv exec is still a problem. Last I heard, @mikz was going to look into it some more.

@mikz
Copy link
Contributor Author

mikz commented Feb 24, 2016

@mattbrictson the example in #311 (comment) should fail also locally, right?

$ rbenv exec /usr/bin/env ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]

Works just fine for me.

We are using this patch in production for few weeks and successfully migrated to ruby 2.2 with this.

Michal Cichra added 2 commits February 24, 2016 10:47
so this example works properly:

  SSHKit.config.command_map[:bundle] = -> { "#{fetch(:ruby_cmd)} /usr/bin/local/bundle" }
it is valid use case to set both command map and prefix
in case of using different binary, the map should still be active
and prefix should be applied as extra

so following example correclty executes rake2.2 within bundler:

  SSHKit.config.command_map[:rake] = 'rake2.2'
  SSHKit.config.command_map.prefix[:rake] = 'bundle exec'

Only drawback is, that resulting command will be:

  bundle exec /usr/bin/env rake2.2
@mikz mikz force-pushed the improve-command-map-prefixes branch from 87d8186 to a13b366 Compare February 24, 2016 09:51
@mikz
Copy link
Contributor Author

mikz commented Feb 24, 2016

Rebased this to be mergeable again.

@mattbrictson I really don't have any server with rbenv. If you have any, could you try to do a deploy with this? I tried those commands locally and all works. From all the source code, it should be just fine. Wrapping a command in /usr/bin/env, rbenv exec or bundle exec does the same thing. Just adds environment and execs that command. All those can be chained together as they just modify the env.

@leehambley
Copy link
Member

I'll see if I can check now.

@mattbrictson
Copy link
Member

Unfortunately it doesn't work in my local environment (OS X).

$ rbenv exec /usr/bin/env ruby -v
rbenv: /usr/bin/env: command not found
$ rbenv --version
rbenv 1.0.0
$ bash --version
GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)

@mattbrictson
Copy link
Member

Just to prove it works without the rbenv exec part:

$ /usr/bin/env ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin14]

@mikz
Copy link
Contributor Author

mikz commented Feb 24, 2016

@mattbrictson that is so weird. It works for me. Also rbenv 1.0.0. Both in zsh and bash.

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)

zsh 5.0.8 (x86_64-apple-darwin15.0)

I edited by /usr/local/Cellar/rbenv/1.0.0/libexec/rbenv-exec and added there echo at the line before the exec and here is output for some commands i tried:

$ rbenv exec ruby -v                                                                                                                                                                        ruby-2.3.0
exec -a ruby /Users/mikz/.rvm/rubies/ruby-2.3.0/bin/ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
$ rbenv exec bash --version                                                                                                                                                                 ruby-2.3.0
exec -a bash /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
$ rbenv exec env bash --version                                                                                                                                                             ruby-2.3.0
exec -a env /usr/bin/env bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
$ rbenv exec /usr/bin/env bash --version                                                                                                                                                    ruby-2.3.0
exec -a /usr/bin/env /usr/bin/env bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)

I really don't see how that could fail. Could you also try running:

exec -a /usr/bin/env /usr/bin/env bash --version
exec /usr/bin/env bash --version
exec -a /usr/bin/env /usr/bin/env ruby --version

I have no idea how to reproduce this. That really should not happen AFAIK.

@mattbrictson
Copy link
Member

Well, clearly something strange is going on. My own OS X machine fails (rbenv installed via Homebrew), and other Ubuntu VMs that I have also fail (rbenv installed via Git clone). However, just now I provisioned a brand new Ubuntu 14.04 VM, installed rbenv, and rbenv exec works fine there.

Perhaps it is a certain rbenv plugin that is causing issues, but I'm grasping at straws here. I'll try to figure it out.

@mattbrictson
Copy link
Member

I've narrowed it down: rbenv fails and prints command not found on when it reaches this line: https://github.com/rbenv/rbenv/blob/e851250da66307a2584218b555068c941b493d44/libexec/rbenv-exec#L33

@mikz
Copy link
Contributor Author

mikz commented Feb 24, 2016

So: rbenv which /usr/bin/env fails for you? What about rbenv which env ?

Could you try to run it with RBENV_DEBUG=1 ?

Internally it is using command like: command -v /usr/bin/env (no message, just error code).

There are some script inclusions, that could affect it. It is hard to help when I can't make it fail.

edit:
it looks like it has to be there: https://github.com/rbenv/rbenv/blob/e851250da66307a2584218b555068c941b493d44/libexec/rbenv-which#L52-L58

@mattbrictson
Copy link
Member

OK, if you look here: https://github.com/rbenv/rbenv/blob/e851250da66307a2584218b555068c941b493d44/libexec/rbenv-which#L38-L43

Then you'll see that rbenv-which only searches the PATH if the current version is system. Otherwise rbenv will search the bin directory of the current Ruby version, which of course doesn't have a binary named env or bash.

Example:

$ rbenv version
2.3.0 (set by /Users/mbrictson/.rbenv/version)
$ rbenv which /usr/bin/env
rbenv: /usr/bin/env: command not found
$ rbenv which env
rbenv: env: command not found

But if I switch to system, then:

$ rbenv shell system
$ rbenv which /usr/bin/env
/usr/bin/env
$ rbenv which env
/usr/bin/env

Long story short, it only works if you don't have a default version set (and are therefore using the system version).

@mikz
Copy link
Contributor Author

mikz commented Feb 24, 2016

So. You cannot run ANY command that is not provided by ruby, via rbenv exec ? Wow.

Ok. Guess that is not going away no matter how wrong it is.

Lets figure out a way to disable this in the capistrano-rbenv plugin? Would you think that would be the right place to do so?

@mattbrictson
Copy link
Member

Honestly I'm not sure how to approach this. I don't use capistrano-rbenv in production, so I'm probably not a good person to give advice.

But to recap: my understanding is that capistrano-rbenv prefixes known Ruby binaries (e.g. rake, bundler) with rbenv exec. If these are not mapped, then SSHKit's default map comes into play, which is to add /usr/bin/env. And so (with this PR) you end up with rbenv exec /usr/bin/env rake, which fails.

There isn't really an SSHKit API to disable the default env mapping, except to add a new mapping. So I suppose capistrano-rbenv could add a "noop" mapping for the known Ruby binaries. But then that would clobber any user-provided mappings.

I don't see a way out. What's your take?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants