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.
> 
> 
> Hi!
> 
> I seek help with fixing
> 
> https://bugs.debian.org/714606
> 
> aka
> 
> https://github.com/net-ssh/net-ssh/issues/110
> 
> 
> The error message on trying ssh.exec is:
> 
> /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:305:in 
> `open_channel': can't add a new key into hash during iteration (RuntimeError)
> 
> 
> Here is the offending source:
> 
> https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh/connection/session.rb#L306
> 
> 
> As far as I get the error is due to method exed in same file using
> 
> open_channel do |channel|
> 
> which then puts the assignment
> 
> channels[local_id] = channel
> 
> in open_channel into an iteration.
> 
> But I asked on #ruby-de and the do / end there is a block, not an iteration.
> 
> However in the backtrace there is
> 
> /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:305:in 
> `open_channel': can't add a new key into hash during iteration (RuntimeError)
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:329:in 
> `exec'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:363:in 
> `exec!'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:174:in 
> `block in commit'
>         from /usr/lib/ruby/vendor_ruby/net/sftp/request.rb:87:in `call'
>         from /usr/lib/ruby/vendor_ruby/net/sftp/request.rb:87:in `respond_to'
>         from /usr/lib/ruby/vendor_ruby/net/sftp/session.rb:948:in 
> `dispatch_request'
>         from /usr/lib/ruby/vendor_ruby/net/sftp/session.rb:911:in 
> `when_channel_polled'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/channel.rb:311:in 
> `call'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/channel.rb:311:in 
> `process'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:222:in 
> `block in preprocess'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:222:in 
> `each'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:222:in 
> `preprocess'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:205:in 
> `process'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:169:in 
> `block in loop'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:169:in 
> `loop'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:169:in 
> `loop'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/channel.rb:269:in 
> `wait'
>         from /usr/lib/ruby/vendor_ruby/net/ssh/connection/session.rb:364:in 
> `exec!'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:184:in 
> `commit'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:628:in 
> `handle_host'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:703:in 
> `block in handle_gwhost'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:686:in `each'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:686:in 
> `handle_gwhost'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:718:in `loop'
>         from /homelokal/ms/Debian/distkeys/distkeys.git/distkeys:828:in 
> `<main>'
> 
> 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
> 
> 
> 
> Do you see a way to fix this up without changing the semantics of 
> open_channel?

Okay, I now got further help from #ruby-de and there is a fix I can do inside 
distkeys:

                ok=false
                @sftp.lstat( ".ssh" ) do |response| ok = response.ok?; end
                if not ok then
                                puts "~/.ssh does not seem to exist, creating 
it with 700..."
                                @ssh.exec!( "mkdir ~/.ssh" )
                                @ssh.exec!( "chmod 700 ~/.ssh" )
                end

i.e. first finish sftp then to the ssh exec stuff.

Pushed:
https://github.com/teamix/distkeys/commit/1092384f54d6531ce1106c4fe7b2f6833a2bba5b


I can now fix all other occurences of this in my script.

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.

Thanks,

-- 
Martin Steigerwald  | Consultant / Trainer

teamix GmbH
Südwestpark 43
90449 Nürnberg

Tel.:  +49 911 30999 55 | Fax: +49 911 30999 99
mail: martin.steigerw...@teamix.de | web:  http://www.teamix.de | blog: 
http://blog.teamix.de

Amtsgericht Nürnberg, HRB 18320 | Geschäftsführer: Oliver Kügow, Richard Müller


** Data Management Day | 29.04.2015 bei teamix **
Jetzt anmelden unter www.teamix.de/CommVault


--
To UNSUBSCRIBE, email to debian-ruby-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: https://lists.debian.org/1907949.nkFR7zgFFT@mango

Reply via email to