On 14/04/15 at 15:12 +0200, Martin Steigerwald wrote: > Am Dienstag, 14. April 2015, 14:39:04 schrieb David Suarez: > > Hi, > > > > 2015-04-14 13:00 GMT+02:00 Martin Steigerwald <m...@teamix.de>: > > > Am Dienstag, 14. April 2015, 12:36:33 schrieb Martin Steigerwald: > > >> Cc'ing the bug report as well, feel free to drop the cc for discussion > > >> on mailing list. > > >> an each in session.rb, line 222. > > >> > > >> > > >> Which looks quite central to the working of ruby-net-ssh to me > > >> > > >> # This is called internally as part of #process. It dispatches any > > >> # available incoming packets, and then runs > > >> Net::SSH::Connection::Channel#process > > >> # for any active channels. If a block is given, it is invoked at the > > >> # start of the method and again at the end, and if the block ever > > >> returns > > >> # false, this method returns false. Otherwise, it returns true. > > >> def preprocess > > >> return false if block_given? && !yield(self) > > >> dispatch_incoming_packets > > >> channels.each { |id, channel| channel.process unless > > >> channel.closing? } > > >> return false if block_given? && !yield(self) > > >> return true > > >> end > > >> > > >> > > >> > > >> The calling site inside distkeys is: > > >> > > >> https://github.com/teamix/distkeys/blob/master/distkeys#L174 > > >> > > > > You are right, 'channels' Hash is modified inside 'channels.each' call. > > > > > I am not sure whether it is a work-around or whether it is a valid > > > contraint to be taken into account when using ruby-net-ssh. To me it > > > feels like a work-around, but well… if it works this way. > > > > > > If you still have an idea how to fix it in ruby-net-ssh, please tell me. > > > > Seems like a valid constrain, due that the problem arise when you are > > trying to open a new channel (ssh.exec!) inside the processing block > > of the another channel (sftp.lstat) in the same ssh session. > > > > One fix could be that instead os reusing the actual ssh connection to > > open the sftp one ""@sftp = Net::SFTP::Session.new(@ssh)"", create a > > new sftp connection ""Net::SFTP.start(host, user, options)"". > > Thanks. > > I now just finish the sftp operation before doing the ssh.exec calls and > this appears to work. Just uploaded distkeys-1.1 to github including 1.1 > debian package source. This also fixes the same for the replacing of > authorized_keys with authorized_keys-new which was racy before due to > work-arounding this issue by deleting first and then sftp.rename() which > in current ruby-net-sftp cannot overwrite a file. > > This appears to work just nice. And I also documented this behavior in > the script. > > Will test internally for a while and then probably reapproach with request > for sponsoring for distkeys. Maybe one day will get distkeys into Debian, > I think its quite useful, cause it can put ssh keys to hosts behind > firewalls using ssh port forwarding automatically. After Jessie release :). > > As for this bug, if you think its a valid constraint, feel free to close it. > > I still think it would be good to at least have this documented somewhere > with ruby-net-ssh, cause the interference between ssh and sftp calls are not > that obvious but due to a implementation detail. > > But I can try to send a documentation patch upstream.
Hi, I don't think that this is a bug in ruby-net-ssh, as the inability to modify a hash during iteration is a Ruby limitation. See e.g: irb(main):005:0> h = { :a => 1} => {:a=>1} irb(main):006:0> h.each_pair { |k, v| h[:b] = 2 } RuntimeError: can't add a new key into hash during iteration from (irb):6:in `block in irb_binding' from (irb):6:in `each_pair' from (irb):6 from /usr/bin/irb:11:in `<main>' I'm closing this bug. Lucas