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

Switching user and invoking other task #268

Closed
mcb opened this issue Jul 27, 2015 · 7 comments
Closed

Switching user and invoking other task #268

mcb opened this issue Jul 27, 2015 · 7 comments

Comments

@mcb
Copy link

mcb commented Jul 27, 2015

This problem occurs when invoking one task from another, it seems like the user context is switched once again and replaced with the default user defined in the server role.

namespace :test do
  task :whoami_task do
    on roles(:all) do
      capture(:whoami)
    end
  end

  task :sudo do
    on roles(:all) do
      as 'runner' do
        invoke 'test:whoami_task'
      end
    end
  end
end

If I call the cap test:sudo task, I would expect the whoami_task to output runner however it returns the user defined in the server role. Is there any way of persisting the user context across tasks?

Background: I am trying to call a task inside another gem and would like to not have the author modify his gem, but need to switch user due to a dual user concept, where one user deploys and another user runs the deployed code.

@leehambley
Copy link
Member

I'm sorry the as documentation lists what is possible, when calling invoke this is something from Rake and the context is lost. We take the blocks passed to as, within, etc and do a lot of juggling of instance variables to make this work, when you call invoke() you jump outside our control

@leehambley
Copy link
Member

I hasten to add that this behaviour is arguably correct, as as, within and friends all belong to SSHKit and invoke belongs to Rake, and they can't, and shouldn't know about each other. I'm strongly tempted to close the issue since I don't think that's how this should work, and I don't consider it to be broken.

For the case that you need to do something like this, you should write a class which encapsulates the logic, and perhaps takes a binding from the current context, to do the work given the original binding, but that runs a serious risk of being inelegant if done incorrectly.

@mcb
Copy link
Author

mcb commented Jul 28, 2015

@leehambley Thanks for clarifying, however implementing a binding class is not an option. I might have a chat with the maintainer of the projects that we use if there is something we can do about it, though it is sad we cannot support it right out of capistrano / sshkit itself.

@mcb mcb closed this as completed Jul 28, 2015
@robd
Copy link
Contributor

robd commented Jul 28, 2015

@mcb I have an idea for a feature which would allow you to set up default options in the command map. This would allow you to hook certain commands and provide your own option for them which I discussed in #234 (comment). This doesn't allow persisting of context across roles, but it would let you set up options based on the command:

SSHKit.config.command_map.default_options[:your_command] = {
  user: 'runner'
}

Would this be helpful?

@mcb
Copy link
Author

mcb commented Jul 28, 2015

@robd Actually this would be very helpful, as I just need to switch user for different tasks. One question though: Would this require the runner User to have a ssh login?

@robd
Copy link
Contributor

robd commented Jul 28, 2015

No, ssh login wouldn't be required. The user: 'runner' option is what happens behind the scenes when you call as: 'runner'. When you call as, it sets up some temporary state on the backend, which is then passed to the Command as the user option. Therefore, this would be equivalent to calling as 'runner' do....

This enhancement is probably quite a way off. I don't have any time right now to work on SSHKit, but it's useful to know whether it would solve problems people are having.

@leehambley
Copy link
Member

though it is sad we cannot support it right out of capistrano / sshkit itself.

That's true, however remember that there's value in projects that have a smaller, more predictable, more reliable API, sometimes this comes at the expense of interoperability and convenience, but I hope we manage to get the balance right, more often than not :)

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

No branches or pull requests

3 participants