Module: Train

Defined in:
lib/train/errors.rb,
lib/train.rb,
lib/train/options.rb,
lib/train/plugins.rb,
lib/train/version.rb

Overview

Author

Dominik Richter (<[email protected]>)

Defined Under Namespace

Modules: Extras, Options, Transports Classes: ClientError, Plugins, TransportError, UserError

Constant Summary collapse

VERSION =
'0.25.0'.freeze

Class Method Summary collapse

Class Method Details

.create(name, *args) ⇒ Transport

Create a new transport instance, with the plugin indicated by the given name.

Parameters:

  • name (String)

    of the plugin

  • *args (Array)

    list of arguments for the plugin

Returns:

  • (Transport)

    instance of the new transport or nil



18
19
20
21
# File 'lib/train.rb', line 18

def self.create(name, *args)
  cls = load_transport(name)
  cls.new(*args) unless cls.nil?
end

.group_keys_and_keyfiles(conf) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/train.rb', line 141

def self.group_keys_and_keyfiles(conf)
  # in case the user specified a key-file, register it that way
  # we will clear the list of keys and put keys and key_files separately
  keys_mixed = conf[:keys]
  return if keys_mixed.nil?

  conf[:key_files] = []
  conf[:keys] = []
  keys_mixed.each do |key|
    if !key.nil? and File.file?(key)
      conf[:key_files].push(key)
    else
      conf[:keys].push(key)
    end
  end
end

.load_transport(name) ⇒ Train::Transport

Load the transport plugin indicated by name. If the plugin is not yet found in the plugin registry, it will be attempted to load from ‘train/transports/plugin_name`.

Parameters:

  • name (String)

    of the plugin

Returns:

  • (Train::Transport)

    the transport plugin



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/train.rb', line 38

def self.load_transport(name)
  res = Train::Plugins.registry[name.to_s]
  return res unless res.nil?

  # if the plugin wasnt loaded yet:
  require 'train/transports/' + name.to_s
  Train::Plugins.registry[name.to_s]
rescue LoadError => _
  raise Train::UserError,
        "Can't find train plugin #{name.inspect}. Please install it first."
end

.options(name) ⇒ Hash

Retrieve the configuration options of a transport plugin.

Parameters:

  • name (String)

    of the plugin

Returns:

  • (Hash)

    map of default options



27
28
29
30
# File 'lib/train.rb', line 27

def self.options(name)
  cls = load_transport(name)
  cls.default_options unless cls.nil?
end

.plugin(version = 1) ⇒ Transport

Create a new plugin by inheriting from the class returned by this method. Create a versioned plugin by providing the transport layer plugin version to this method. It will then select the correct class to inherit from.

The plugin version determins what methods will be available to your plugin.

Parameters:

  • version (Int) (defaults to: 1)

    1 the plugin version to use

Returns:

  • (Transport)

    the versioned transport base class



31
32
33
34
35
36
37
38
39
# File 'lib/train/plugins.rb', line 31

def self.plugin(version = 1)
  if version != 1
    fail ClientError,
         'Only understand train plugin version 1. You are trying to '\
         "initialize a train plugin #{version}, which is not supported "\
         'in the current release of train.'
  end
  ::Train::Plugins::Transport
end

.target_config(config = nil) ⇒ Object

Resolve target configuration in URI-scheme into all respective fields and merge with existing configuration. e.g. ssh://bob@remote => backend: ssh, user: bob, host: remote



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/train.rb', line 53

def self.target_config(config = nil) # rubocop:disable Metrics/AbcSize
  conf = config.nil? ? {} : config.dup
  conf = symbolize_keys(conf)

  group_keys_and_keyfiles(conf)

  return conf if conf[:target].to_s.empty?

  # split up the target's host/scheme configuration
  uri = parse_uri(conf[:target].to_s)
  unless uri.host.nil? and uri.scheme.nil?
    conf[:backend]  ||= uri.scheme
    conf[:host]     ||= uri.hostname
    conf[:port]     ||= uri.port
    conf[:user]     ||= uri.user
    conf[:password] ||= uri.password
    conf[:path]     ||= uri.path
  end

  # ensure path is nil, if its empty; e.g. required to reset defaults for winrm
  conf[:path] = nil if !conf[:path].nil? && conf[:path].to_s.empty?

  # return the updated config
  conf
end

.validate_backend(conf, default = :local) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/train.rb', line 117

def self.validate_backend(conf, default = :local)
  return default if conf.nil?
  res = conf[:backend]

  if (res.nil? || res == 'localhost') && conf[:sudo]
    fail Train::UserError, 'Sudo is only valid when running against a remote host. '\
      'To run this locally with elevated privileges, run the command with `sudo ...`.'
  end

  return res if !res.nil?

  if !conf[:target].nil?
    fail Train::UserError, 'Cannot determine backend from target '\
         "configuration #{conf[:target].inspect}. Valid example: ssh://192.168.0.1."
  end

  if !conf[:host].nil?
    fail Train::UserError, 'Host configured, but no backend was provided. Please '\
         'specify how you want to connect. Valid example: ssh://192.168.0.1.'
  end

  conf[:backend] = default
end