-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
su - USER command execution support & change transport_options to attr_accessor #636
su - USER command execution support & change transport_options to attr_accessor #636
Conversation
- Set transport options whenever required. - su - USER command execution using -c require password - Append su_password option if command execution required password. Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
Hello vsingh-msys! Thanks for the pull request! Here is what will happen next:
Thank you for contributing! |
yield(data) if block_given? | ||
stdout += data | ||
if data == "Password: " | ||
channel.send_data "#{@transport_options[:su_password]}\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use the accessor. Also it looks like any time the data contains "Password: " the su_password will be output, even if it is not set? It also isn't clear to me why this isn't just done
in the caller by passing a block that looks for "Password: " and outputs the su_password, and why this needs to go into train.
Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
@@ -316,12 +316,12 @@ def execute_on_channel(cmd) | |||
channel.exec(cmd) do |_, success| | |||
abort "Couldn't execute command on SSH." unless success | |||
channel.on_data do |_, data| | |||
yield(data) if block_given? | |||
yield(data, channel) if block_given? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we can consume this on the train side with password the data block
require 'train'
train = Train.create('ssh', host: 'node1.test', port: 22, user: 'vagrant', key_files: './.vagrant/machines/default/virtualbox/private_key', pty: true)
conn = train.connection
password = "PASSWORD"
res = conn.run_command("su - root -c 'date;'") do |data, ch|
ch.send_data("#{password}\n") if data.match?("Password:")
end
puts "STDOUT: #{res.stdout}"
puts "STDERR: #{res.stderr}"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested using the given code and it does work. I also verified that the new block parameter is optional, so any existing code that calls run_command without the channel
param will not break.
This does put all of the responsibility for handling the password on the calling code.
stdout += data | ||
end | ||
|
||
channel.on_extended_data do |_, _type, data| | ||
yield(data) if block_given? | ||
yield(data, channel) if block_given? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passed channel
to block yield to maintain the parity with on_data
block.
Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
if output && output.match?("su: Authentication failure") | ||
raise Train::UserError.new(output, :bad_su_user_password) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap the su: Authentication failure
run_command error message and raise custom Train::UserError
with reason bad_su_user_password
Any suggestions for class and reason naming I would be happy to discuss?
@clintoncwolfe could you please have a look? Thanks! |
@clintoncwolfe Any chance you can chime in on this change? |
attr_reader :hostname | ||
attr_reader :transport_options | ||
attr_reader :hostname | ||
attr_accessor :transport_options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you help me understand why this change is needed? I don't see anywhere in the PR what the transport_option ivar is directly changed, and if you need to change one of its elements you can do so without making it read-write.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the context where the goal is to change the pty option to true later in the process:
https://github.com/chef/chef/pull/10410/files#r492238172
I had the same question, but didn't know enough about train to suggest anything better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work OK with the ssh code here that looks at the options to determine if the connection can be re-used or needs restarted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@james-stocks As we memoinzed the connection object at chef core side https://github.com/chef/chef/blob/0a29892953b07ba1fded119f5aef364e14c7dd07/lib/chef/knife/bootstrap/train_connector.rb#L51-L59, won't be a problem here, but not sure about other impacts.
Description
su - USER -c 'ls;date;'
su_password
option if command execution required a password.Related Issue
Fixes: #633
Types of changes
Checklist:
Signed-off-by: Vivek Singh vivek.singh@msystechnologies.com