Issue Invoking Knife SSH from Ruby script
gmacgregor1 opened this issue · 7 comments
Description
I am unable to invoke knife::ssh from a ruby script after specifying all the required config information. Basically trying to location a directory on a large group of servers using ruby scripting instead of knife commands, and I upgraded chefDK to 3.1.0 from 2.(something) and now I am getting the following error:
#<Thread:0x0000000003cf14a0@/home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:554 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
4: from /home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:555:in `block (2 levels) in realize_pending_connections!'
3: from /home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:60:in `replace_with'
2: from /home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:60:in `each'
1: from /home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:60:in `block in replace_with'
/home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:29:in `replay_on': undefined method `open_channel' for nil:NilClass (NoMethodError)
ChefDK Version
Chef Development Kit Version: 3.1.0
chef-client version: 14.2.0
delivery version: master (6862f27aba89109a9630f0b6c6798efec56b4efe)
berks version: 7.0.4
kitchen version: 1.22.0
inspec version: 2.1.72
Platform Version
centos-release-7-5.1804.el7.centos.2.x86_64
Replication Case
I pass all the values in via a json config file, and parse them using OpenStruct.
def knife_ssh (env, concurrency, chef_path, identity_file, chef_api_key, chef_api_user, name_args, stage)
ssh_user = 'root'
config_file = File.join("#{chef_path}", 'knife', "#{env}", 'knife.rb')
knife = Chef::Knife::Ssh.new
knife.name_args = name_args
knife.config[:ssh_user] = ssh_user
knife.config[:concurrency] = concurrency
knife.config[:config_file] = config_file
knife.config[:ssh_identity_file] = identity_file
knife.config[:client_key] = chef_api_key
knife.config[:api_key] = chef_api_key
knife.config[:api_client_user] = chef_api_user
stdout = StringIO.new
stderr = StringIO.new
knife.ui = Chef::Knife::UI.new(stdout, stderr, STDIN, {})
knife.configure_chef
puts "Running Knife on #{env}! Please Wait...."
knife.run
Chef::Knife::Ssh.reset_config_loader!
end
Omitted some specific output, but I can include that if it is required.
/home/gmacgregor1/.chefdk/gem/ruby/2.5.0/gems/net-ssh-multi-1.2.1
indicates that this is failing in a custom gem that the user has installed, I'd try nuking that gem as if it's using that codepath then it's not ChefDK code that is breaking.
Knife isn't really meant to be used as a library and I'm curious why you're not just using net-ssh directly.
Knife is a CLI tool, not a library. We do not support this kind of usage. Use net-ssh and friends directly instead.
@coderanger Hmm, if its only a CLI tool, why does this exist https://www.rubydoc.info/github/opscode/chef/Chef/Knife/Ssh...
from https://docs.chef.io/plugin_knife_custom.html
def knife_ssh
ssh = Chef::Knife::Ssh.new
ssh.ui = ui
ssh.name_args = [ server_name, ssh_command ]
ssh.config[:ssh_user] = Chef::Config[:knife][:ssh_user] || config[:ssh_user]
ssh.config[:ssh_password] = config[:ssh_password]
ssh.config[:ssh_port] = Chef::Config[:knife][:ssh_port] || config[:ssh_port]
ssh.config[:ssh_gateway] = Chef::Config[:knife][:ssh_gateway] || config[:ssh_gateway]
ssh.config[:identity_file] = Chef::Config[:knife][:identity_file] || config[:identity_file]
ssh.config[:manual] = true
ssh.config[:host_key_verify] = Chef::Config[:knife][:host_key_verify] || config[:host_key_verify]
ssh.config[:on_error] = :raise
ssh
end
Also this was working in chefdk 2.(something) and worked very well, when I upgraded to the newer version I figured I wouldn't have much issues.
And I am not using net-ssh directly as I would like to use the knife search function to go through the list of nodes, instead of bashing-out.
That reference is merely an example of how knife ssh checks config values internally, nothing more. The fact that RubyDocs exists is a side effect of this being a gem, no implied contract or support.
Moreover, as I pointed out the source of your issue is gems you specifically installed to the DK that aren't the built-in gems.
@cheeseplus net-ssh-multi was installed by the chefdk rpm I initially installed it. I haven't installed any gems within ~/.chefdk manually.
same error on a fresh install of centos and chefdk
#<Thread:0x00007fd46c137cc8@/opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:554 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
4: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:555:in `block (2 levels) in realize_pending_connections!'
3: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:60:in `replace_with'
2: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:60:in `each'
1: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:60:in `block in replace_with'
/opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/pending_connection.rb:29:in `replay_on': undefined method `open_channel' for nil:NilClass (NoMethodError)
I think i have a way around it, but this gem is in-fact used by Knife to do concurrent sessions.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.