Class: DeploYML::RemoteShell

Inherits:
Shell
  • Object
show all
Defined in:
lib/deployml/remote_shell.rb

Overview

Represents a shell running on a remote server.

Instance Attribute Summary collapse

Attributes inherited from Shell

#uri

Instance Method Summary collapse

Methods inherited from Shell

#exec, #rake, #rake_task, #status

Constructor Details

#initialize(uri) {|session| ... } ⇒ RemoteShell

Initializes a remote shell session.

Parameters:

  • uri (Addressable::URI, String)

    The URI of the host to connect to.

Yields:

  • (session)

    If a block is given, it will be passed the new remote shell session.

Yield Parameters:

  • session (ShellSession)

    The remote shell session.



27
28
29
30
31
32
33
# File 'lib/deployml/remote_shell.rb', line 27

def initialize(uri,&block)
  @history = []

  super(uri,&block)

  replay if block
end

Instance Attribute Details

#historyObject (readonly)

The history of the Remote Shell



13
14
15
# File 'lib/deployml/remote_shell.rb', line 13

def history
  @history
end

Instance Method Details

#cd(path) { ... } ⇒ Object

Enqueues a directory change for the session.

Parameters:

  • path (String)

    The path of the new current working directory to use.

Yields:

  • [] If a block is given, then the directory will be changed back after the block has returned.



68
69
70
71
72
73
74
75
# File 'lib/deployml/remote_shell.rb', line 68

def cd(path)
  @history << ['cd', path]

  if block_given?
    yield
    @history << ['cd', '-']
  end
end

#echo(message) ⇒ Object

Enqueues an echo command to be ran in the session.

Parameters:

  • message (String)

    The message to echo.



54
55
56
# File 'lib/deployml/remote_shell.rb', line 54

def echo(message)
  run 'echo', message
end

#joinString

Joins the command history together with &&, to form a single command.

Returns:

  • (String)

    A single command string.



84
85
86
87
88
# File 'lib/deployml/remote_shell.rb', line 84

def join
  @history.map { |command|
    command.map { |word| shellescape(word.to_s) }.join(' ')
  }.join(' && ')
end

#replayObject

Replays the command history on the remote server.



136
137
138
# File 'lib/deployml/remote_shell.rb', line 136

def replay
  ssh(self.join) unless @history.empty?
end

#run(program, *arguments) ⇒ Object

Enqueues a program to be ran in the session.

Parameters:

  • program (String)

    The name or path of the program to run.

  • arguments (Array<String>)

    Additional arguments for the program.



44
45
46
# File 'lib/deployml/remote_shell.rb', line 44

def run(program,*arguments)
  @history << [program, *arguments]
end

#shellescape(str) ⇒ String (protected)

Note:

Vendored from shellwords.rb line 72 from Ruby 1.9.2.

Escapes a string so that it can be safely used in a Bourne shell command line.

Note that a resulted string should be used unquoted and is not intended for use in double quotes nor in single quotes.

Examples:

open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
  # ...
}

Parameters:

  • str (String)

    The string to escape.

Returns:

  • (String)

    The shell-escaped string.



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/deployml/remote_shell.rb', line 162

def shellescape(str)
  # An empty argument will be skipped, so return empty quotes.
  return "''" if str.empty?

  str = str.dup

  # Process as a single byte sequence because not all shell
  # implementations are multibyte aware.
  str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")

  # A LF cannot be escaped with a backslash because a backslash + LF
  # combo is regarded as line continuation and simply ignored.
  str.gsub!(/\n/, "'\n'")

  return str
end

#ssh(*arguments) ⇒ Object

Starts a SSH session with the destination server.

Parameters:

  • arguments (Array)

    Additional arguments to pass to SSH.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/deployml/remote_shell.rb', line 116

def ssh(*arguments)
  options = []

  # Add the -p option if an alternate destination port is given
  if @uri.port
    options += ['-p', @uri.port.to_s]
  end

  # append the SSH URI
  options << ssh_uri

  # append the additional arguments
  arguments.each { |arg| options << arg.to_s }

  return system('ssh',*options)
end

#ssh_uriString

Converts the URI to one compatible with SSH.

Returns:

  • (String)

    The SSH compatible URI.

Raises:

  • (InvalidConfig)

    The URI of the shell does not have a host component.



99
100
101
102
103
104
105
106
107
108
# File 'lib/deployml/remote_shell.rb', line 99

def ssh_uri
  unless @uri.host
    raise(InvalidConfig,"URI does not have a host: #{@uri}",caller)
  end

  new_uri = @uri.host
  new_uri = "#{@uri.user}@#{new_uri}" if @uri.user

  return new_uri
end