[DRE-maint] Bug#714606: help with fixing ruby-net-ssh: can't add a new key into hash during iteration during ssh.exec

Martin Steigerwald ms at teamix.de
Tue Apr 14 10:36:33 UTC 2015


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?


Another conclusion would be to treat ruby-net-ssh as unfit for release
with Debian Jessie, as a central functionality just does not work with Ruby
1.9+, and Jessie does not have Ruby 1.8 anymore.

But even tough upstream appears to be basically unmaintained (see note
about maintenance note at https://github.com/net-ssh/net-ssh) I think it would
be nice to have this fixed. But anyway, if its unmaintained it may be better
to remove it? I don't know about any other free as in freedom alternative to
it tough.

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.steigerwald at 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



More information about the Pkg-ruby-extras-maintainers mailing list