Module: Train

Defined in:
lib/train/errors.rb,
lib/train.rb,
lib/train/file.rb,
lib/train/globals.rb,
lib/train/options.rb,
lib/train/plugins.rb,
lib/train/version.rb,
lib/train/file/local.rb,
lib/train/file/remote.rb,
lib/train/file/local/unix.rb,
lib/train/file/remote/aix.rb,
lib/train/file/remote/qnx.rb,
lib/train/file/remote/unix.rb,
lib/train/file/remote/linux.rb,
lib/train/file/local/windows.rb,
lib/train/file/remote/windows.rb

Overview

Author

Dominik Richter (<[email protected]>)

Defined Under Namespace

Modules: Extras, Options, Platforms, Transports Classes: ClientError, Error, File, PlatformDetectionFailed, PluginLoadError, Plugins, TransportError, UnknownCacheType, UserError

Constant Summary collapse

VERSION =
'1.7.1'.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



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

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

.group_keys_and_keyfiles(conf) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/train.rb', line 160

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(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



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/train.rb', line 39

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

  # Try to load the transport name from the core transports...
  require 'train/transports/' + transport_name
  return Train::Plugins.registry[transport_name]
rescue LoadError => _
  begin
    # If it's not in the core transports, try loading from a train plugin gem.
    gem_name = 'train-' + transport_name
    require gem_name
    return Train::Plugins.registry[transport_name]
    # rubocop: disable Lint/HandleExceptions
  rescue LoadError => _
    # rubocop: enable Lint/HandleExceptions
    # Intentionally empty rescue - we're handling it below anyway
  end

  ex = Train::PluginLoadError.new("Can't find train plugin #{transport_name}. Please install it first.")
  ex.transport_name = transport_name
  raise ex
end

.options(name) ⇒ Hash

Retrieve the configuration options of a transport plugin.

Parameters:

  • name (String)

    of the plugin

Returns:

  • (Hash)

    map of default options



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

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

.src_rootObject



2
3
4
# File 'lib/train/globals.rb', line 2

def self.src_root
  File.expand_path(File.join(__FILE__, '..', '..', '..'))
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



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/train.rb', line 67

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[:path]     ||= uri.path
    conf[:password] ||=
      if conf[:www_form_encoded_password] && !uri.password.nil?
        URI.decode_www_form_component(uri.password)
      else
        uri.password
      end
  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



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/train.rb', line 136

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