chef: Knife SSH error using sudo and targeting multiple hosts
Description
After upgrading Chef Workstation from 20.9.148 to the latest (20.12.206) I’m seeing issues with knife ssh.
When running a command with sudo via knife ssh targeting multiple hosts, I get the following error:
Logs
❯ knife ssh 'name:test-i-* AND chef_environment:dev-*' 'sudo echo hello' -VV -t 2 -P
INFO: Using configuration from /Users/evanvandam/.chef/config.rb
Enter your password:
DEBUG: Using node attribute 'fqdn' as the ssh target: test-i-0a536f894e86fe33e.usw2-dev1.example.com
DEBUG: Using node attribute 'fqdn' as the ssh target: test-i-0d4edbb4165388860.usw2-dev1.example.com
DEBUG: Using node attribute 'fqdn' as the ssh target: test-i-0aef2ce5202bcdac2.usw2-dev1.example.com
DEBUG: Using node attribute 'fqdn' as the ssh target: test-i-0454550cb3edc6caa.usw2-dev1.example.com
DEBUG: Adding test-i-0a536f894e86fe33e.usw2-dev1.example.com
DEBUG: Adding test-i-0d4edbb4165388860.usw2-dev1.example.com
DEBUG: Adding test-i-0aef2ce5202bcdac2.usw2-dev1.example.com
DEBUG: Adding test-i-0454550cb3edc6caa.usw2-dev1.example.com
Traceback (most recent call last):
26: from /opt/chef-workstation/bin/knife:343:in `<main>'
25: from /opt/chef-workstation/bin/knife:343:in `load'
24: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/bin/knife:24:in `<top (required)>'
23: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/application/knife.rb:165:in `run'
22: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife.rb:229:in `run'
21: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife.rb:489:in `run_with_pretty_exceptions'
20: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/local_mode.rb:42:in `with_server_connectivity'
19: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife.rb:490:in `block in run_with_pretty_exceptions'
18: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:630:in `run'
17: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:362:in `ssh_command'
16: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:399:in `open_session'
15: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:417:in `loop'
14: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:417:in `loop'
13: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:417:in `block in loop'
12: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:430:in `process'
11: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:449:in `preprocess'
10: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server_list.rb:45:in `each'
9: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server_list.rb:45:in `each'
8: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server_list.rb:47:in `block in each'
7: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:449:in `block in preprocess'
6: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server.rb:205:in `preprocess'
5: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:240:in `preprocess'
4: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:248:in `ev_preprocess'
3: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:548:in `dispatch_incoming_packets'
2: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:673:in `channel_extended_data'
1: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/channel.rb:598:in `do_extended_data'
/opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:388:in `block (3 levels) in open_session': ArgumentError (ArgumentError)
27: from /opt/chef-workstation/bin/knife:343:in `<main>'
26: from /opt/chef-workstation/bin/knife:343:in `load'
25: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/bin/knife:24:in `<top (required)>'
24: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/application/knife.rb:165:in `run'
23: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife.rb:229:in `run'
22: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife.rb:489:in `run_with_pretty_exceptions'
21: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/local_mode.rb:42:in `with_server_connectivity'
20: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife.rb:490:in `block in run_with_pretty_exceptions'
19: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:630:in `run'
18: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:361:in `ssh_command'
17: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:364:in `rescue in ssh_command'
16: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:399:in `open_session'
15: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:417:in `loop'
14: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:417:in `loop'
13: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:417:in `block in loop'
12: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:430:in `process'
11: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:449:in `preprocess'
10: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server_list.rb:45:in `each'
9: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server_list.rb:45:in `each'
8: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server_list.rb:47:in `block in each'
7: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/session.rb:449:in `block in preprocess'
6: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/server.rb:205:in `preprocess'
5: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:240:in `preprocess'
4: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:248:in `ev_preprocess'
3: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:548:in `dispatch_incoming_packets'
2: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:673:in `channel_extended_data'
1: from /opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/channel.rb:598:in `do_extended_data'
/opt/chef-workstation/embedded/lib/ruby/gems/2.7.0/gems/chef-16.8.14/lib/chef/knife/ssh.rb:388:in `block (3 levels) in open_session': ArgumentError (ArgumentError)
Chef Version
❯ chef --version
Chef Workstation version: 20.12.206
Chef Infra Client version: 16.8.14
Chef InSpec version: 4.24.8
Chef CLI version: 3.0.33
Chef Habitat version: 1.6.181
Test Kitchen version: 2.8.0
Cookstyle version: 7.3.11
Platform Version
MacOS 10.15.7
Replication Case
The issue only seems to happen when the command uses sudo, when targeting multiple hosts.
# Use -P for sudo password, use sudo in the command, target multiple hosts. This will fail.
❯ knife ssh 'name:test-*' 'sudo echo hello' -VV -t 2 -P
# Use -P for sudo password, don't use sudo in the command, target multiple hosts. This will succeed.
❯ knife ssh 'name:test-*' 'echo hello' -VV -t 2 -P
# Use -P for sudo password, use sudo in the command, target a single host. This will succeed.
❯ knife ssh 'name:test-12345' 'echo hello' -VV -t 2 -P
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 35 (26 by maintainers)
Updated for newest workstation with new knife gem
In #9482 it was added in 506876bf5b3cafb015ad9e22a62b76af5021b6e9, however the suggestion was made to remove the flag, catch the error and retry. If the flag can be added (and set in knife config) it would work for us. Or a solution that handles the race condition. But my guess is that fixing the race condition is a lot harder than adding the flag.
After some more digging, it looks to be related to the change made in #9482.
From that moment it changes the behaviour to request a pty only if an error is thrown (regarding the pty). The option to always request a pty was removed in 21f975163cf041af0f132a30ad3525e2e727d2a2. When I change the default to request a pty (
pty = truein the method definition) I no longer run into the ArgumentError.I’ve consistently never seen a
sudo anythingwork since my Chef Workstation updated to 20ishIt’s only a problem if there are multiple targets to the
knife ssh, my workaround currently is to for loop them all as single targets which works but is not optimal. It’s via-m xyz pdqor with asearch queryIt’s definitely something to do with the sudo because if I have a team mate with his old version of Chef Workstation run the same command, it works and mine will then work because of the cached for 5 minutes or so sudo priv elevation. But as soon as that priv escalation by myuser expires, you will start getting the Argument Errors, it’s only when sudo asks for a password on multiple targets. If sudo has a cached escalation already then it won’t ask for a password and the command will work.
@indygwyn : for our team I’ve created a script which we can run after an upgrade of Chef Workstation, I’ve shared it as a gist if you’re interested: https://gist.github.com/fuegas/e60fdb5ea74bc808dda4c3355d9a78e0
Edit: altered the script to work with the native stat of OS-X.