Class: Gofer::Host

Inherits:
Object
  • Object
show all
Defined in:
lib/gofer/host.rb

Overview

A persistent, authenticated SSH connection to a single host.

Connections are persistent, but not encapsulated within a shell. This means that while it won't need to reconnect & re-authenticate for each operation, don't assume that environment variables will be persisted between commands like they will in a shell-based SSH session.

/etc/ssh/config and ~/.ssh/config are not recognized by Net::SSH, and thus not recognized by Gofer::Host.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(_hostname, username, opts = {}) ⇒ Host

Create a new connection to a host

Passed options not included in the below are passed directly to Net::SSH.start. See net-ssh.github.com/ssh/v2/api/index.html for valid arguments.

Options:

quiet

Don't print stdout output from run commands

output_prefix

Prefix each line of stdout and stderr to differentiate multiple host output


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/gofer/host.rb', line 29

def initialize _hostname, username, opts={}
  @hostname = _hostname

  # support legacy positional argument use
  if opts.is_a? String
    warn "Gofer::Host.new identify file positional argument will be removed in 1.0, use :keys instead"
    opts = { :keys => [opts]}
  end

  @quiet = opts.delete(:quiet)
  @output_prefix = opts.delete(:output_prefix)

  # support legacy identity_file argument
  if opts[:identity_file]
    warn "Gofer::Host.new option :identify_file will be removed in 1.0, use :keys instead"
    opts[:keys] = [opts.delete(:identity_file)]
  end

  @ssh = SshWrapper.new(hostname, username, opts)
end

Instance Attribute Details

#hostnameObject (readonly)

Returns the value of attribute hostname


16
17
18
# File 'lib/gofer/host.rb', line 16

def hostname
  @hostname
end

#output_prefixObject

Returns the value of attribute output_prefix


17
18
19
# File 'lib/gofer/host.rb', line 17

def output_prefix
  @output_prefix
end

#quietObject

Returns the value of attribute quiet


17
18
19
# File 'lib/gofer/host.rb', line 17

def quiet
  @quiet
end

Instance Method Details

#directory?(path) ⇒ Boolean

Returns true if path is a directory, false otherwise.

Returns:

  • (Boolean)

87
88
89
# File 'lib/gofer/host.rb', line 87

def directory? path
  @ssh.run("sh -c '[ -d #{path} ]'").exit_status == 0
end

#download(from, to, opts = {}) ⇒ Object

Downloads the file or directory at from to to

Options:

recursive: Perform a recursive download, similar to scp -r. true by default if from is a directory.


115
116
117
# File 'lib/gofer/host.rb', line 115

def download from, to, opts = {}
  @ssh.download from, to, {:recursive => directory?(from)}.merge(opts)
end

#exist?(path) ⇒ Boolean

Returns true if path exists, false otherwise.

Returns:

  • (Boolean)

77
78
79
# File 'lib/gofer/host.rb', line 77

def exist? path
  @ssh.run("sh -c '[ -e #{path} ]'").exit_status == 0
end

#ls(path) ⇒ Object

Returns a list of the files in the directory at path.


92
93
94
95
96
97
98
99
# File 'lib/gofer/host.rb', line 92

def ls path
  response = @ssh.run "ls -1 #{path}", :quiet => true
  if response.exit_status == 0
    response.stdout.strip.split("\n")
  else
    raise HostError.new(self, response, "Could not list #{path}, exit status #{response.exit_status}")
  end
end

#read(path) ⇒ Object

Returnss the contents of the file at path.


82
83
84
# File 'lib/gofer/host.rb', line 82

def read path
  @ssh.read_file path
end

#run(command, opts = {}) ⇒ Object

Run command.

Will raise an error if command exits with a non-zero status, unless capture_exit_status is true.

Print stdout and stderr as they're received.

Returns an intance of Gofer::Response, containing captured stdout, stderr, and an exit status if capture_exit_status is true.

Options:

quiet

Don't print stdout, can also be set with quiet= on the instance

quiet_stderr

Don't print stderr

capture_exit_status

Don't raise an error on a non-zero exit status

stdin

Send a string on stdin then close the file


66
67
68
69
70
71
72
73
74
# File 'lib/gofer/host.rb', line 66

def run command, opts={}
  opts[:quiet] = quiet unless opts.include?(:quiet)
  opts[:output_prefix] = @output_prefix
  response = @ssh.run command, opts
  if !opts[:capture_exit_status] && response.exit_status != 0
    raise HostError.new(self, response, "Command #{command} failed with exit status #{@ssh.last_exit_status}")
  end
  response
end

#upload(from, to, opts = {}) ⇒ Object

Uploads the file or directory at from to to.

Options:

recursive: Perform a recursive upload, similar to scp -r. true by default if from is a directory.


106
107
108
# File 'lib/gofer/host.rb', line 106

def upload from, to, opts = {}
  @ssh.upload from, to, {:recursive => File.directory?(from)}.merge(opts)
end

#write(data, to) ⇒ Object

Writes data to a file at to


120
121
122
123
124
125
126
# File 'lib/gofer/host.rb', line 120

def write data, to
  Tempfile.open "gofer_write" do |file|
    file.write data
    file.close
    @ssh.upload(file.path, to, :recursive => false)
  end
end