Class: Babushka::SSH

Inherits:
Object show all
Defined in:
lib/babushka/ssh.rb

Overview

Represents an ssh connection to a remote host.

This class prioritises simplicity over performance; there's no connection re-use, or any state apart from the address of the host. Every connection is new and independent of any others.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host) ⇒ SSH

Returns a new instance of SSH.


15
16
17
# File 'lib/babushka/ssh.rb', line 15

def initialize host
  @host = host
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host


13
14
15
# File 'lib/babushka/ssh.rb', line 13

def host
  @host
end

Instance Method Details

#babushka(dep_spec, args = {}) ⇒ Object

Run babushka on the remote host with the given dep specification and arguments, logging the remote command and its output.

Functionally, this is identical to running babushka manually on the remote commandline, except that the remote stdin is not a terminal.


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/babushka/ssh.rb', line 47

def babushka dep_spec, args = {}
  remote_args = [
    '--defaults',
    '--show-args',
    ('--git-fs' if Babushka::Base.task.opt(:remote_git_fs)),
    # No need to send --no-colour explicitly. The remote won't use colour
    # except with an explicit --colour, because its STDOUT isn't a tty.
    ('--colour' if Babushka::Base.task.opt(:"[no_]color")),
    ('--update' if Babushka::Base.task.opt(:update)),
    ('--debug'  if Babushka::Base.task.opt(:debug))
  ].compact

  dep_args = args.keys.map {|k| "#{k}=#{Shellwords.escape(args[k].to_s)}" }.sort

  remote_args.concat(dep_args)

  log_shell('babushka', Shellwords.escape(dep_spec), *remote_args).tap {|result|
    raise Babushka::UnmeetableDep, "The remote babushka reported an error." unless result
  }
end

#log_shell(*cmd) ⇒ Object

Log the command to be run on the remote host, including argument details, and then run it using #shell within an indented log block. The result of the command will be logged at the end of the indented section.


31
32
33
34
35
36
37
38
39
40
# File 'lib/babushka/ssh.rb', line 31

def log_shell *cmd
  cmd_message = [
    host.colorize("on grey"),
    cmd.map {|i| i.sub(/^(.{40})(.).+/m, '\1…') }.join(' ') # Truncate long args
  ].join(' $ ')

  LogHelpers.log cmd_message, :closing_status => cmd_message do
    shell(*cmd)
  end
end

#shell(*cmd) ⇒ Object

Run cmd on the remote host via ssh. Arguments will be escaped for the shell as required.


21
22
23
24
25
26
# File 'lib/babushka/ssh.rb', line 21

def shell *cmd
  # We would do this, but ruby 1.8 can't handle options after a splat:
  #   ShellHelpers.shell("ssh", "-A", host, *cmd, :log => true)
  args = ["ssh", "-A", host].concat(cmd).push(:log => true)
  ShellHelpers.shell(*args)
end