diff -r 7013280e62fa -r ffa70066522c lib/symphony/tasks/sshscript.rb --- a/lib/symphony/tasks/sshscript.rb Wed May 28 11:45:41 2014 -0700 +++ b/lib/symphony/tasks/sshscript.rb Thu Jul 12 15:25:35 2018 -0700 @@ -1,12 +1,13 @@ #!/usr/bin/env ruby # vim: set nosta noet ts=4 sw=4: +require 'securerandom' require 'net/ssh' require 'net/sftp' -require 'tmpdir' require 'inversion' require 'symphony' require 'symphony/task' +require 'symphony/tasks/ssh' ### A base class for connecting to a remote host, then uploading and @@ -26,9 +27,10 @@ ### key: (optional) The path to an SSH private key ### attributes: (optional) Additional data to attach to the template ### nocleanup: (optional) Leave the remote script after execution? (default to false) +### tempdir: (optional) The destination temp directory. (defaults to /tmp) ### ### -### Additionally, this class responds to the 'symphony_ssh' configurability +### Additionally, this class responds to the 'symphony.ssh' configurability ### key. Currently, you can override the default ssh user and private key. ### ### Textual output of the command is stored in the @output instance variable. @@ -49,53 +51,27 @@ ### end ### class Symphony::Task::SSHScript < Symphony::Task - extend Configurability - config_key :symphony_ssh # Template config # TEMPLATE_OPTS = { - :ignore_unknown_tags => false, - :on_render_error => :propagate, - :strip_tag_lines => true + ignore_unknown_tags: false, + on_render_error: :propagate, + strip_tag_lines: true } # The defaults to use when connecting via SSH # DEFAULT_SSH_OPTIONS = { - :auth_methods => [ 'publickey' ], - :compression => true, - :config => false, - :keys_only => true, - :paranoid => false, - :global_known_hosts_file => '/dev/null', - :user_known_hosts_file => '/dev/null' - } - - # SSH default options. - # - CONFIG_DEFAULTS = { - :user => 'root', - :key => nil + auth_methods: [ 'publickey' ], + compression: true, + config: false, + keys_only: true, + verify_host_key: :never, + global_known_hosts_file: '/dev/null', + user_known_hosts_file: '/dev/null' } - class << self - # The default user to use when connecting. If unset, 'root' is used. - attr_reader :user - - # An absolute path to a password-free ssh private key. - attr_reader :key - end - - ### Configurability API. - ### - def self::configure( config=nil ) - config = Symphony::Task::SSHScript.defaults.merge( config || {} ) - @user = config.delete( :user ) - @key = config.delete( :key ) - super - end - ### Perform the ssh connection, render the template, send it, and ### execute it. @@ -104,20 +80,21 @@ template = payload[ 'template' ] attributes = payload[ 'attributes' ] || {} port = payload[ 'port' ] || 22 - user = payload[ 'user' ] || Symphony::Task::SSHScript.user - key = payload[ 'key' ] || Symphony::Task::SSHScript.key + user = payload[ 'user' ] || Symphony::Task::SSH.user + key = payload[ 'key' ] || Symphony::Task::SSH.key nocleanup = payload[ 'nocleanup' ] + tempdir = payload[ 'tempdir' ] || '/tmp' raise ArgumentError, "Missing required option 'template'" unless template - raise ArgumentError, "Missing required option 'host'" unless payload[ 'host' ] + raise ArgumentError, "Missing required option 'host'" unless payload[ 'host' ] - remote_filename = self.make_remote_filename( template ) + remote_filename = self.make_remote_filename( template, tempdir ) source = self.generate_script( template, attributes ) - ssh_options = DEFAULT_SSH_OPTIONS.merge( :port => port, :keys => [key] ) + ssh_options = DEFAULT_SSH_OPTIONS.merge( port: port, keys: Array(key) ) ssh_options.merge!( - :logger => Loggability[ Net::SSH ], - :verbose => :debug + logger: Loggability[ Net::SSH ], + verbose: :debug ) if payload[ 'debug' ] Net::SSH.start( payload['host'], user, ssh_options ) do |conn| @@ -141,11 +118,15 @@ ### Generate a unique filename for the script on the remote host, ### based on +template+ name. ### - def make_remote_filename( template ) + def make_remote_filename( template, tempdir="/tmp" ) basename = File.basename( template, File.extname(template) ) - tmpname = Dir::Tmpname.make_tmpname( basename, rand(10000) ) + tmpname = "%s/%s-%s" % [ + tempdir, + basename, + SecureRandom.hex( 6 ) + ] - return "/tmp/#{tmpname}" + return tmpname end