Class: Cartage::Remote::Host

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

Overview

The Host which remote commands will be run on.

Constant Summary collapse

HOST_RE =
/\A(?:(?<user>[^@]+)@)?(?<address>[^@:]+)(?::(?<port>[^:]+))?\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, ssh_config = nil) ⇒ Host

Initialize the Host from a host object (an OpenStruct from a parsed Cartage configuration) or a host string ([user@]address[:port]).

If ssh_config is provided, prepare the SSH connections.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/cartage/remote/host.rb', line 39

def initialize(host, ssh_config = nil)
  @keys = @key_data = @build = @prebuild = @postbuild = nil

  case host
  when OpenStruct
    @user = host.user
    @address = host.address || host.host
    @port = host.port

    if host.keys.kind_of?(OpenStruct)
      @key_data = host.keys.to_h.values
    elsif host.keys
      @keys = Array(host.keys).flat_map { |key|
        Pathname.glob(Pathname(key).expand_path)
      }.uniq
    end

    # If key_data or keys are empty, properly empty them so that they are
    # handled improperly.
    @key_data = nil if @key_data && @key_data.empty?
    @keys = nil if @keys && @keys.empty?

    @build = host.build
    @prebuild = host.prebuild
    @postbuild = host.postbuild
  when HOST_RE
    @user = Regexp.last_match[:user]
    @address = Regexp.last_match[:address]
    @port = Regexp.last_match[:port]
  end

  if address.nil? || address.empty?
    fail ArgumentError, 'Invalid remote host, no address specified.'
  end

  @user = ENV['USER'] if user.nil? || user.empty?

  configure_ssh(ssh_config) if ssh_config
end

Instance Attribute Details

#addressObject (readonly)

The address of the remote host.



9
10
11
# File 'lib/cartage/remote/host.rb', line 9

def address
  @address
end

#buildObject (readonly)

The (optional) build script defined as part of this host.



14
15
16
# File 'lib/cartage/remote/host.rb', line 14

def build
  @build
end

#key_dataObject (readonly)

The (optional) array of SSH private keys defined as part of this host.



24
25
26
# File 'lib/cartage/remote/host.rb', line 24

def key_data
  @key_data
end

#keysObject (readonly)

The (optional) array of SSH private key filenames defined as part of this host.



22
23
24
# File 'lib/cartage/remote/host.rb', line 22

def keys
  @keys
end

#portObject (readonly)

The port of the SSH connection to the remote host.



11
12
13
# File 'lib/cartage/remote/host.rb', line 11

def port
  @port
end

#postbuildObject (readonly)

The (optional) postbuild script defined as part of this host.



18
19
20
# File 'lib/cartage/remote/host.rb', line 18

def postbuild
  @postbuild
end

#prebuildObject (readonly)

The (optional) prebuild script defined as part of this host.



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

def prebuild
  @prebuild
end

#scpObject (readonly)

The Fog::SCP instance for this server. Must run #configure_ssh before using.



31
32
33
# File 'lib/cartage/remote/host.rb', line 31

def scp
  @scp
end

#sshObject (readonly)

The Fog::SSH instance for this server. Must run #configure_ssh before using.



28
29
30
# File 'lib/cartage/remote/host.rb', line 28

def ssh
  @ssh
end

#userObject (readonly)

The user on the remote host.



7
8
9
# File 'lib/cartage/remote/host.rb', line 7

def user
  @user
end

Instance Method Details

#configure_ssh(ssh_config) ⇒ Object

Configure the Fog::SSH and Fog::SCP connections using the provided ssh_config.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/cartage/remote/host.rb', line 81

def configure_ssh(ssh_config)
  require 'fog'

  if @key_data
    ssh_config[:key_data] = @key_data
    ssh_config[:keys] = nil
  elsif @keys
    ssh_config[:key_data] = nil
    ssh_config[:keys] = @keys
  end

  options = { paranoid: true, port: port }.
    merge(ssh_config).
    delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }

  @ssh = Fog::SSH.new(address, user, options)
  @scp = Fog::SCP.new(address, user, options)
end

#to_hashObject

Convert this Host to a hash format.



106
107
108
109
110
111
112
# File 'lib/cartage/remote/host.rb', line 106

def to_hash
  {
    user: user,
    address: address,
    port: port
  }.delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
end

#to_sObject

This Host, formatted nicely.



101
102
103
# File 'lib/cartage/remote/host.rb', line 101

def to_s
  "#{user}@#{address}:#{port}".gsub(/^@|:$/, '')
end