Class: Symphony::Task::SSHScript

Inherits:
Symphony::Task
  • Object
show all
Extended by:
Configurability
Defined in:
lib/symphony/tasks/sshscript.rb

Overview

A base class for connecting to a remote host, then uploading and executing an Inversion templated script.

This isn’t designed to be used directly. To use this in your environment, you’ll want to subclass it, add the behaviors that make sense for you, then super() back to the parent in the #work method.

It expects the payload to contain the following keys:

host:       (required) The hostname to connect to
template:   (required) A path to the Inversion templated script
port:       (optional) The port to connect to (defaults to 22)
user:       (optional) The user to connect as (defaults to root)
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)

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.

require 'symphony'
require 'symphony/tasks/sshscript'

class YourTask < Symphony::Task::SSHScript
    timeout 30
    subscribe_to 'ssh.script.*'

    def work( payload,  )
        status = super
        puts "Remote script said: %s" % [ @output ]
        return status.success?
    end
end

Constant Summary collapse

TEMPLATE_OPTS =

Template config

{
	:ignore_unknown_tags => false,
	:on_render_error     => :propagate,
	:strip_tag_lines     => true
}
DEFAULT_SSH_OPTIONS =

The defaults to use when connecting via SSH

{
	:auth_methods            => [ 'publickey' ],
	:compression             => true,
	:config                  => false,
	:keys_only               => true,
	:paranoid                => false,
	:global_known_hosts_file => '/dev/null',
	:user_known_hosts_file   => '/dev/null'
}
CONFIG_DEFAULTS =

SSH default options.

{
	:user => 'root',
	:key  => nil
}

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.keyObject (readonly)

An absolute path to a password-free ssh private key.



87
88
89
# File 'lib/symphony/tasks/sshscript.rb', line 87

def key
  @key
end

.userObject (readonly)

The default user to use when connecting. If unset, ‘root’ is used.



84
85
86
# File 'lib/symphony/tasks/sshscript.rb', line 84

def user
  @user
end

Class Method Details

.configure(config = nil) ⇒ Object

Configurability API.



92
93
94
95
96
97
# File 'lib/symphony/tasks/sshscript.rb', line 92

def self::configure( config=nil )
	config = self.defaults.merge( config || {} )
	@user = config.delete( :user )
	@key  = config.delete( :key )
	super
end

Instance Method Details

#work(payload, metadata) ⇒ Object

Perform the ssh connection, render the template, send it, and execute it.

Raises:

  • (ArgumentError)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/symphony/tasks/sshscript.rb', line 103

def work( payload,  )
	template   = payload[ 'template' ]
	attributes = payload[ 'attributes' ] || {}
	port       = payload[ 'port' ]    || 22
	user       = payload[ 'user' ]    || Symphony::Task::SSHScript.user
	key        = payload[ 'key'  ]    || Symphony::Task::SSHScript.key
	nocleanup  = payload[ 'nocleanup' ]

	raise ArgumentError, "Missing required option 'command'" unless template
	raise ArgumentError, "Missing required option 'host'"    unless payload[ 'host' ]

	remote_filename = self.make_remote_filename( template )
	source = self.generate_script( template, attributes )

	ssh_options = DEFAULT_SSH_OPTIONS.merge( :port => port, :keys => [key] )
	ssh_options.merge!(
		:logger  => Loggability[ Net::SSH ],
		:verbose => :debug
	) if payload[ 'debug' ]

	Net::SSH.start( payload['host'], user, ssh_options ) do |conn|
		self.log.debug "Uploading script (%d bytes) to %s:%s." %
			[ source.bytesize, payload['host'], remote_filename ]
		self.upload_script( conn, source, remote_filename )
		self.log.debug "  done with the upload."

		self.run_script( conn, remote_filename, nocleanup )
		self.log.debug "Output was:\n#{@output}"
	end

	return true
end