Jamis,
No worries - take your time.
Joe
On Oct 24, 3:36 pm, Jamis Buck <[EMAIL PROTECTED]> wrote:
> Joe,
>
> I apologize for not getting back to you earlier on that. I haven't
> had a chance to look over the patch carefully, so I was waiting until
> that happened...but I've been so overwhelmed with things to do that
> it hasn't happened yet. :(
>
> I'm not sure how quickly I'll be back to get to it, but since it's on
> trac, it won't get overlooked at least, like patches tend to be when
> they're only posted on the list.
>
> - Jamis
>
> On Oct 24, 2007, at 1:24 PM, Joe wrote:
>
>
>
> > Jamis,
>
> > I created a bug on Trac for this, #9933. When you get a chance, take a
> > look and let me know if it is along the correct lines. I added some
> > notes about things that are incomplete, but that I didn't want to
> > start on until I had a feel for whether it was headed in the right
> > direction.
>
> > Thanks,
> > Joe
>
> > On Oct 13, 3:13 pm, Joe <[EMAIL PROTECTED]> wrote:
> >> Jamis,
>
> >> Here's a first cut at a proper patch, done against the repo head.
>
> >> A few things to note. I'm not sure if the user_for methods should be
> >> pushed into the connection factories. For now, I just did that, but
> >> since both eventually call SSH.connect, it could presumably be pulled
> >> up.
>
> >> The @sessions variable is now a hash of hashes, and the
> >> @failed_sessions is now a hash of arrays. For both, the first hash
> >> key
> >> is the server. For the @sessions variable, the second hash's key is
> >> the current user. For @failed_sessions, this is stored in the array,
> >> indexed by server.
>
> >> The connect_to now lazily establishes a connection based on the
> >> server
> >> and user for that server, with the user being determined by server
> >> user, options user, or ssh_options[:username], in that order.
>
> >> Therunmethod now takes :as, and restores the :user variable when it
> >> is done.
>
> >> Finally, this doesn't do anything with :password right now. I'm not
> >> sure how that should be handled, and I wanted to see how you felt
> >> about this first before delving into that.
>
> >> This passes the full test suite, though there are no new tests for
> >> this code yet.
>
> >> Joe
>
> >> Index: test/configuration/connections_test.rb
> >> ===================================================================
> >> --- test/configuration/connections_test.rb (revision 7860)
> >> +++ test/configuration/connections_test.rb (working copy)
> >> @@ -87,8 +87,8 @@
> >> end
>
> >> def
> >> test_establish_connections_to_should_not_attempt_to_reestablish_exist
> >> ing_co nnections
> >> - Capistrano::SSH.expects(:connect).times(2).returns(:success)
> >> - @config.sessions[server("cap1")] = :ok
> >> + Capistrano::SSH.expects(:connect).times(3).returns(:success)
> >> + @config.establish_connections_to(%w(cap1).map { |s| server(s) })
> >> @config.establish_connections_to(%w(cap1 cap2 cap3).map { |s|
> >> server(s) })
> >> assert %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s|
> >> s.host }
> >> end
> >> Index: lib/capistrano/ssh.rb
> >> ===================================================================
> >> --- lib/capistrano/ssh.rb (revision 7860)
> >> +++ lib/capistrano/ssh.rb (working copy)
> >> @@ -105,5 +105,9 @@
> >> retry
> >> end
> >> end
> >> +
> >> + def self.user_for(server, options={})
> >> + server.user || options[:user] || (options[:ssh_options] || {})
> >> [:username]
> >> + end
> >> end
> >> end
> >> Index: lib/capistrano/gateway.rb
> >> ===================================================================
> >> --- lib/capistrano/gateway.rb (revision 7860)
> >> +++ lib/capistrano/gateway.rb (working copy)
> >> @@ -113,6 +113,10 @@
> >> connection
> >> end
>
> >> + def user_for(server)
> >> + SSH.user_for(server, @options)
> >> + end
> >> +
> >> private
>
> >> def logger
> >> Index: lib/capistrano/configuration/actions/invocation.rb
> >> ===================================================================
> >> --- lib/capistrano/configuration/actions/invocation.rb (revision
> >> 7860)
> >> +++ lib/capistrano/configuration/actions/invocation.rb (working
> >> copy)
> >> @@ -48,9 +48,19 @@
>
> >> options = add_default_command_options(options)
>
> >> - execute_on_servers(options) do |servers|
> >> - targets = servers.map { |s| sessions[s] }
> >> - Command.process(cmd, targets, options.merge(:logger =>
> >> logger), &block)
> >> + as = options.delete(:as)
> >> + begin
> >> + u = fetch(:user, nil)
> >> + if as
> >> + reset!(:password)
> >> + set(:user, as) if as
> >> + end
> >> + execute_on_servers(options) do |servers|
> >> + targets = servers.map { |s| sessions[s] }
> >> + Command.process(cmd, targets, options.merge(:logger =>
> >> logger), &block)
> >> + end
> >> + ensure
> >> + set(:user, u) if as
> >> end
> >> end
>
> >> Index: lib/capistrano/configuration/connections.rb
> >> ===================================================================
> >> --- lib/capistrano/configuration/connections.rb (revision 7860)
> >> +++ lib/capistrano/configuration/connections.rb (working copy)
> >> @@ -19,29 +19,45 @@
> >> def connect_to(server)
> >> SSH.connect(server, @options)
> >> end
> >> +
> >> + def user_for(server)
> >> + SSH.user_for(server, @options)
> >> + end
> >> end
> >> +
> >> + def initialize_with_connections(*args) #:nodoc:
> >> + initialize_without_connections(*args)
> >> + @sessions = {}
> >> + @failed_sessions = {}
> >> + end
>
> >> + # Obtain the username that is used for logins based on the
> >> current settings
> >> + def user_for(server)
> >> + connection_factory.user_for(server)
> >> + end
> >> +
> >> # A hash of the SSH sessions that are currently open and
> >> available.
> >> # Because sessions are constructed lazily, this will only
> >> contain
> >> # connections to those servers that have been the targets of
> >> one or more
> >> # executed tasks.
> >> - attr_reader :sessions
> >> -
> >> - def initialize_with_connections(*args) #:nodoc:
> >> - initialize_without_connections(*args)
> >> - @sessions = {}
> >> - @failed_sessions = []
> >> + def sessions
> >> + @sessions.keys.inject({}) do |result, server|
> >> + result[server] = @sessions[server][user_for(server)]
> >> + result
> >> + end
> >> end
> >> -
> >> +
> >> # Indicate that the given server could not be connected to.
> >> def failed!(server)
> >> - @failed_sessions << server
> >> + @failed_sessions[server] ||= []
> >> + @failed_sessions[server] << user_for(server)
> >> end
>
> >> # Query whether previous connection attempts to the given
> >> server have
> >> # failed.
> >> def has_failed?(server)
> >> - @failed_sessions.include?(server)
> >> + return false if not @failed_sessions.has_key?(server)
> >> + @failed_sessions[server].include?(user_for(server))
> >> end
>
> >> # Used to force connections to be made to the current task's
> >> servers.
> >> @@ -141,6 +157,8 @@
>
> >> private
>
> >> + attr_writer :sessions
> >> +
> >> # We establish the connection by creating a thread in a new
> >> method--this
> >> # prevents problems with the thread's scope seeing the wrong
> >> 'server'
> >> # variable if the thread just happens to take too long to
> >> start up.
> >> @@ -149,7 +167,8 @@
> >> end
>
> >> def safely_establish_connection_to(server, failures=nil)
> >> - sessions[server] ||= connection_factory.connect_to(server)
> >> + @sessions[server] ||= {}
> >> + @sessions[server][user_for(server)] ||=
> >> connection_factory.connect_to(server)
> >> rescue Exception => err
> >> raise unless failures
> >> failures << { :server => server, :error => err }
>
> >> On Oct 13, 12:35 pm, Joe <[EMAIL PROTECTED]> wrote:
>
> >>> Jamis,
>
> >>> Ok, thanks, I will. I think the main thing will be to check if the
> >>> user has changed for the session, and close it conditionally, or
> >>> cache
> >>> the open one with the different username. Additionally, it'd have to
> >>> cache the password for the different users.
>
> >>> Joe
>
> >>> On Oct 12, 4:16 pm, Jamis Buck <[EMAIL PROTECTED]> wrote:
>
> >>>> I wouldn't be opposed to a patch for this, but as you discovered,
> >>>> Capistrano currently makes some assumptions that make it hard to do
> >>>> this "right". Feel free to write up a patch, though, and we can
> >>>> negotiate the correct implementation. :)
>
> >>>> - Jamis
>
> >>>> On Oct 11, 2007, at 6:24 PM, Joe wrote:
>
> >>>>> Hi Jamis,
>
> >>>>> I have another feature request for you. I have a deployment
> >>>>> where I
> >>>>> have a series of tasks that get executed on various machines,
> >>>>> but I
> >>>>> need to login to those machines with public key auth with
> >>>>> different
> >>>>> user ids. In this particular scenario, using sudo does not
> >>>>> really work
> >>>>> as needed. What I want to do is something like:
>
> >>>>> run"some_command", :as => 'root'
>
> >>>>> which temporarily changes the 'user' variable for the duration
> >>>>> of the
> >>>>> execution of the task.
>
> >>>>> I accomplish this by aliasing therunmethod as follows:
>
> >>>>> module CapistranoExt
> >>>>> class Configuration
> >>>>> module Actions
> >>>>> module Invocation
> >>>>> def self.append_features(base)
> >>>>> super
> >>>>> base.extend(ClassMethods)
> >>>>> base.class_eval do
> >>>>> alias_method_chain :run, :user
> >>>>> end
> >>>>> end
>
> >>>>> module ClassMethods
> >>>>> end
>
> >>>>> # TODO: this really only works if the authentication
> >>>>> method is
> >>>>> # publickey, since the password is cached from a call
> >>>>> to the
> >>>>> # proc to read it. Need to have a mechanism to cache
> >>>>> that per
> >>>>> # user, and set it appropriately in here (if we need to
> >>>>> support
>
> ...
>
> read more ยป
>
> smime.p7s
> 3KDownload
--~--~---------~--~----~------------~-------~--~----~
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/capistrano
-~----------~----~----~----~------~----~------~--~---