train 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +71 -0
- data/CHANGELOG.md +308 -0
- data/Gemfile +30 -0
- data/LICENSE +201 -0
- data/README.md +156 -0
- data/Rakefile +148 -0
- data/lib/train.rb +117 -0
- data/lib/train/errors.rb +23 -0
- data/lib/train/extras.rb +17 -0
- data/lib/train/extras/command_wrapper.rb +148 -0
- data/lib/train/extras/file_aix.rb +20 -0
- data/lib/train/extras/file_common.rb +161 -0
- data/lib/train/extras/file_linux.rb +16 -0
- data/lib/train/extras/file_unix.rb +79 -0
- data/lib/train/extras/file_windows.rb +91 -0
- data/lib/train/extras/linux_lsb.rb +60 -0
- data/lib/train/extras/os_common.rb +136 -0
- data/lib/train/extras/os_detect_darwin.rb +32 -0
- data/lib/train/extras/os_detect_linux.rb +148 -0
- data/lib/train/extras/os_detect_unix.rb +99 -0
- data/lib/train/extras/os_detect_windows.rb +57 -0
- data/lib/train/extras/stat.rb +133 -0
- data/lib/train/options.rb +80 -0
- data/lib/train/plugins.rb +40 -0
- data/lib/train/plugins/base_connection.rb +86 -0
- data/lib/train/plugins/transport.rb +49 -0
- data/lib/train/transports/docker.rb +103 -0
- data/lib/train/transports/local.rb +52 -0
- data/lib/train/transports/local_file.rb +90 -0
- data/lib/train/transports/local_os.rb +51 -0
- data/lib/train/transports/mock.rb +147 -0
- data/lib/train/transports/ssh.rb +163 -0
- data/lib/train/transports/ssh_connection.rb +225 -0
- data/lib/train/transports/winrm.rb +184 -0
- data/lib/train/transports/winrm_connection.rb +194 -0
- data/lib/train/version.rb +7 -0
- data/test/integration/.kitchen.yml +43 -0
- data/test/integration/Berksfile +3 -0
- data/test/integration/bootstrap.sh +17 -0
- data/test/integration/chefignore +1 -0
- data/test/integration/cookbooks/test/metadata.rb +1 -0
- data/test/integration/cookbooks/test/recipes/default.rb +100 -0
- data/test/integration/cookbooks/test/recipes/prep_files.rb +47 -0
- data/test/integration/docker_run.rb +153 -0
- data/test/integration/docker_test.rb +24 -0
- data/test/integration/docker_test_container.rb +24 -0
- data/test/integration/helper.rb +61 -0
- data/test/integration/sudo/customcommand.rb +15 -0
- data/test/integration/sudo/nopasswd.rb +16 -0
- data/test/integration/sudo/passwd.rb +21 -0
- data/test/integration/sudo/reqtty.rb +17 -0
- data/test/integration/sudo/run_as.rb +12 -0
- data/test/integration/test-travis-1.yaml +13 -0
- data/test/integration/test-travis-2.yaml +13 -0
- data/test/integration/test_local.rb +19 -0
- data/test/integration/test_ssh.rb +39 -0
- data/test/integration/tests/path_block_device_test.rb +74 -0
- data/test/integration/tests/path_character_device_test.rb +74 -0
- data/test/integration/tests/path_file_test.rb +79 -0
- data/test/integration/tests/path_folder_test.rb +90 -0
- data/test/integration/tests/path_missing_test.rb +77 -0
- data/test/integration/tests/path_pipe_test.rb +78 -0
- data/test/integration/tests/path_symlink_test.rb +95 -0
- data/test/integration/tests/run_command_test.rb +28 -0
- data/test/unit/extras/command_wrapper_test.rb +78 -0
- data/test/unit/extras/file_common_test.rb +180 -0
- data/test/unit/extras/linux_file_test.rb +167 -0
- data/test/unit/extras/os_common_test.rb +269 -0
- data/test/unit/extras/os_detect_linux_test.rb +189 -0
- data/test/unit/extras/os_detect_windows_test.rb +99 -0
- data/test/unit/extras/stat_test.rb +148 -0
- data/test/unit/extras/windows_file_test.rb +44 -0
- data/test/unit/helper.rb +7 -0
- data/test/unit/plugins/connection_test.rb +44 -0
- data/test/unit/plugins/transport_test.rb +111 -0
- data/test/unit/plugins_test.rb +22 -0
- data/test/unit/train_test.rb +156 -0
- data/test/unit/transports/local_file_test.rb +184 -0
- data/test/unit/transports/local_test.rb +87 -0
- data/test/unit/transports/mock_test.rb +87 -0
- data/test/unit/transports/ssh_test.rb +109 -0
- data/test/unit/version_test.rb +8 -0
- data/test/windows/local_test.rb +46 -0
- data/test/windows/winrm_test.rb +52 -0
- data/train.gemspec +38 -0
- metadata +295 -0
data/README.md
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
# Train - Transport Interface
|
2
|
+
|
3
|
+
Train lets you talk to your local or remote operating systems with a unified interface.
|
4
|
+
|
5
|
+
It allows you to:
|
6
|
+
|
7
|
+
* execute commands via `run_command`
|
8
|
+
* interact with files via `file`
|
9
|
+
* identify the target operating system via `os`
|
10
|
+
|
11
|
+
Train supports:
|
12
|
+
|
13
|
+
* Local execution
|
14
|
+
* SSH
|
15
|
+
* WinRM
|
16
|
+
* Docker
|
17
|
+
* Mock (for testing and debugging)
|
18
|
+
|
19
|
+
# Examples
|
20
|
+
|
21
|
+
## Setup
|
22
|
+
|
23
|
+
**Local**
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'train'
|
27
|
+
train = Train.create('local')
|
28
|
+
```
|
29
|
+
|
30
|
+
**SSH**
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'train'
|
34
|
+
train = Train.create('ssh',
|
35
|
+
host: '1.2.3.4', port: 22, user: 'root', key_files: '/vagrant')
|
36
|
+
```
|
37
|
+
|
38
|
+
**WinRM**
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require 'train'
|
42
|
+
train = Train.create('winrm',
|
43
|
+
host: '1.2.3.4', user: 'Administrator', password: '...', ssl: true, self_signed: true)
|
44
|
+
```
|
45
|
+
|
46
|
+
**Docker**
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'train'
|
50
|
+
train = Train.create('docker', host: 'container_id...')
|
51
|
+
```
|
52
|
+
|
53
|
+
## Configuration
|
54
|
+
|
55
|
+
To get a list of available options for a plugin:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
puts Train.options('ssh')
|
59
|
+
```
|
60
|
+
This will provide all configuration options:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
{
|
64
|
+
:host => { :required => true},
|
65
|
+
:port => { :default => 22, :required => true},
|
66
|
+
:user => { :default => "root", :required => true},
|
67
|
+
:keys => { :default => nil},
|
68
|
+
:password => { :default => nil},
|
69
|
+
...
|
70
|
+
```
|
71
|
+
|
72
|
+
## Usage
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# start or reuse a connection
|
76
|
+
conn = train.connection
|
77
|
+
|
78
|
+
# run a command on Linux/Unix/Mac
|
79
|
+
puts conn.run_command('whoami').stdout
|
80
|
+
|
81
|
+
# get OS info
|
82
|
+
puts conn.os[:family]
|
83
|
+
puts conn.os[:release]
|
84
|
+
|
85
|
+
# access files
|
86
|
+
puts conn.file('/proc/version').content
|
87
|
+
|
88
|
+
# close the connection
|
89
|
+
conn.close
|
90
|
+
```
|
91
|
+
|
92
|
+
# Testing
|
93
|
+
|
94
|
+
We perform `unit`, `integration` and `windows` tests.
|
95
|
+
|
96
|
+
* `unit` tests ensure the intended behaviour of the implementation
|
97
|
+
* `integration` tests run against VMs and docker containers
|
98
|
+
* `windows` tests that run on appveyor for windows integration tests
|
99
|
+
|
100
|
+
## Windows
|
101
|
+
|
102
|
+
```
|
103
|
+
# run windows tests
|
104
|
+
bundle exec rake test:windows
|
105
|
+
|
106
|
+
# run single tests
|
107
|
+
bundle exec ruby -I .\test\windows\ .\test\windows\local_test.rb
|
108
|
+
```
|
109
|
+
|
110
|
+
|
111
|
+
# Kudos and Contributors
|
112
|
+
|
113
|
+
Train is heavily based on the work of:
|
114
|
+
|
115
|
+
* [test-kitchen](https://github.com/test-kitchen/test-kitchen)
|
116
|
+
|
117
|
+
by [Fletcher Nichol](fnichol@nichol.ca)
|
118
|
+
and [a great community of contributors](https://github.com/test-kitchen/test-kitchen/graphs/contributors)
|
119
|
+
|
120
|
+
* [ohai](https://github.com/chef/ohai)
|
121
|
+
|
122
|
+
by Adam Jacob, Chef Software Inc.
|
123
|
+
and [a great community of contributors](https://github.com/chef/ohai/graphs/contributors)
|
124
|
+
|
125
|
+
|
126
|
+
## Contributing
|
127
|
+
|
128
|
+
1. Fork it
|
129
|
+
1. Create your feature branch (git checkout -b my-new-feature)
|
130
|
+
1. Commit your changes (git commit -am 'Add some feature')
|
131
|
+
1. Push to the branch (git push origin my-new-feature)
|
132
|
+
1. Create new Pull Request
|
133
|
+
|
134
|
+
## License
|
135
|
+
|
136
|
+
| **Author:** | Dominik Richter (<drichter@chef.io>)
|
137
|
+
|
138
|
+
| **Author:** | Christoph Hartmann (<chartmann@chef.io>)
|
139
|
+
|
140
|
+
| **Copyright:** | Copyright (c) 2015 Chef Software Inc.
|
141
|
+
|
142
|
+
| **Copyright:** | Copyright (c) 2015 Vulcano Security GmbH.
|
143
|
+
|
144
|
+
| **License:** | Apache License, Version 2.0
|
145
|
+
|
146
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
147
|
+
you may not use this file except in compliance with the License.
|
148
|
+
You may obtain a copy of the License at
|
149
|
+
|
150
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
151
|
+
|
152
|
+
Unless required by applicable law or agreed to in writing, software
|
153
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
154
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
155
|
+
See the License for the specific language governing permissions and
|
156
|
+
limitations under the License.
|
data/Rakefile
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'bundler'
|
5
|
+
require 'bundler/gem_tasks'
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'rubocop/rake_task'
|
8
|
+
|
9
|
+
# Rubocop
|
10
|
+
desc 'Run Rubocop lint checks'
|
11
|
+
task :rubocop do
|
12
|
+
RuboCop::RakeTask.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# lint the project
|
16
|
+
desc 'Run robocop linter'
|
17
|
+
task lint: [:rubocop]
|
18
|
+
|
19
|
+
# run tests
|
20
|
+
task default: [:test, :lint]
|
21
|
+
|
22
|
+
Rake::TestTask.new do |t|
|
23
|
+
t.libs << 'test/unit'
|
24
|
+
t.pattern = 'test/unit/**/*_test.rb'
|
25
|
+
t.warning = true
|
26
|
+
t.verbose = true
|
27
|
+
t.ruby_opts = ['--dev'] if defined?(JRUBY_VERSION)
|
28
|
+
end
|
29
|
+
|
30
|
+
namespace :test do
|
31
|
+
task :docker do
|
32
|
+
path = File.join(File.dirname(__FILE__), 'test', 'integration')
|
33
|
+
sh('sh', '-c', "cd #{path} && ruby -I ../../lib docker_test.rb tests/*")
|
34
|
+
end
|
35
|
+
|
36
|
+
task :windows do
|
37
|
+
Dir.glob('test/windows/*_test.rb').all? do |file|
|
38
|
+
sh(Gem.ruby, '-w', '-I .\test\windows', file)
|
39
|
+
end or fail 'Failures'
|
40
|
+
end
|
41
|
+
|
42
|
+
task :vm do
|
43
|
+
concurrency = ENV['CONCURRENCY'] || 4
|
44
|
+
path = File.join(File.dirname(__FILE__), 'test', 'integration')
|
45
|
+
sh('sh', '-c', "cd #{path} && kitchen test -c #{concurrency}")
|
46
|
+
end
|
47
|
+
|
48
|
+
# Target required:
|
49
|
+
# rake "test:ssh[user@server]"
|
50
|
+
# sh -c cd /home/foobarbam/src/gems/train/test/integration \
|
51
|
+
# && target=user@server ruby -I ../../lib test_ssh.rb tests/*
|
52
|
+
# ...
|
53
|
+
# Turn debug logging back on:
|
54
|
+
# debug=1 rake "test:ssh[user@server]"
|
55
|
+
# Use a different ssh key:
|
56
|
+
# key_files=/home/foobarbam/.ssh/id_rsa2 rake "test:ssh[user@server]"
|
57
|
+
# Run with a specific test:
|
58
|
+
# test=path_block_device_test.rb rake "test:ssh[user@server]"
|
59
|
+
task :ssh, [:target] do |t, args|
|
60
|
+
path = File.join(File.dirname(__FILE__), 'test', 'integration')
|
61
|
+
key_files = ENV['key_files'] || File.join(ENV['HOME'], '.ssh', 'id_rsa')
|
62
|
+
|
63
|
+
sh_cmd = "cd #{path} && target=#{args[:target]} key_files=#{key_files}"
|
64
|
+
|
65
|
+
sh_cmd += " debug=#{ENV['debug']}" if ENV['debug']
|
66
|
+
sh_cmd += ' ruby -I ../../lib test_ssh.rb tests/'
|
67
|
+
sh_cmd += ENV['test'] || '*'
|
68
|
+
|
69
|
+
sh('sh', '-c', sh_cmd)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Print the current version of this gem or update it.
|
74
|
+
#
|
75
|
+
# @param [Type] target the new version you want to set, or nil if you only want to show
|
76
|
+
def train_version(target = nil)
|
77
|
+
path = 'lib/train/version.rb'
|
78
|
+
require_relative path.sub(/.rb$/, '')
|
79
|
+
|
80
|
+
nu_version = target.nil? ? '' : " -> #{target}"
|
81
|
+
puts "Train: #{Train::VERSION}#{nu_version}"
|
82
|
+
|
83
|
+
unless target.nil?
|
84
|
+
raw = File.read(path)
|
85
|
+
nu = raw.sub(/VERSION.*/, "VERSION = '#{target}'.freeze")
|
86
|
+
File.write(path, nu)
|
87
|
+
load(path)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Check if a command is available
|
92
|
+
#
|
93
|
+
# @param [Type] x the command you are interested in
|
94
|
+
# @param [Type] msg the message to display if the command is missing
|
95
|
+
def require_command(x, msg = nil)
|
96
|
+
return if system("command -v #{x} || exit 1")
|
97
|
+
msg ||= 'Please install it first!'
|
98
|
+
puts "\033[31;1mCan't find command #{x.inspect}. #{msg}\033[0m"
|
99
|
+
exit 1
|
100
|
+
end
|
101
|
+
|
102
|
+
# Check if a required environment variable has been set
|
103
|
+
#
|
104
|
+
# @param [String] x the variable you are interested in
|
105
|
+
# @param [String] msg the message you want to display if the variable is missing
|
106
|
+
def require_env(x, msg = nil)
|
107
|
+
exists = `env | grep "^#{x}="`
|
108
|
+
return unless exists.empty?
|
109
|
+
puts "\033[31;1mCan't find environment variable #{x.inspect}. #{msg}\033[0m"
|
110
|
+
exit 1
|
111
|
+
end
|
112
|
+
|
113
|
+
# Check the requirements for running an update of this repository.
|
114
|
+
def check_update_requirements
|
115
|
+
require_command 'git'
|
116
|
+
require_command 'github_changelog_generator', "\n"\
|
117
|
+
"For more information on how to install it see:\n"\
|
118
|
+
" https://github.com/skywinder/github-changelog-generator\n"
|
119
|
+
require_env 'CHANGELOG_GITHUB_TOKEN', "\n"\
|
120
|
+
"Please configure this token to make sure you can run all commands\n"\
|
121
|
+
"against GitHub.\n\n"\
|
122
|
+
"See github_changelog_generator homepage for more information:\n"\
|
123
|
+
" https://github.com/skywinder/github-changelog-generator\n"
|
124
|
+
end
|
125
|
+
|
126
|
+
# Show the current version of this gem.
|
127
|
+
desc 'Show the version of this gem'
|
128
|
+
task :version do
|
129
|
+
train_version
|
130
|
+
end
|
131
|
+
|
132
|
+
desc 'Generate the changelog'
|
133
|
+
task :changelog do
|
134
|
+
require_relative 'lib/train/version'
|
135
|
+
system "github_changelog_generator -u chef -p train --future-release #{Train::VERSION}"
|
136
|
+
end
|
137
|
+
|
138
|
+
# Update the version of this gem and create an updated
|
139
|
+
# changelog. It covers everything short of actually releasing
|
140
|
+
# the gem.
|
141
|
+
desc 'Bump the version of this gem'
|
142
|
+
task :bump_version, [:version] do |_, args|
|
143
|
+
v = args[:version] || ENV['to']
|
144
|
+
fail "You must specify a target version! rake bump_version to=1.2.3" if v.empty?
|
145
|
+
check_update_requirements
|
146
|
+
train_version(v)
|
147
|
+
Rake::Task['changelog'].invoke
|
148
|
+
end
|
data/lib/train.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
4
|
+
|
5
|
+
require 'train/version'
|
6
|
+
require 'train/plugins'
|
7
|
+
require 'train/errors'
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module Train
|
11
|
+
# Create a new transport instance, with the plugin indicated by the
|
12
|
+
# given name.
|
13
|
+
#
|
14
|
+
# @param [String] name of the plugin
|
15
|
+
# @param [Array] *args list of arguments for the plugin
|
16
|
+
# @return [Transport] instance of the new transport or nil
|
17
|
+
def self.create(name, *args)
|
18
|
+
cls = load_transport(name)
|
19
|
+
cls.new(*args) unless cls.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Retrieve the configuration options of a transport plugin.
|
23
|
+
#
|
24
|
+
# @param [String] name of the plugin
|
25
|
+
# @return [Hash] map of default options
|
26
|
+
def self.options(name)
|
27
|
+
cls = load_transport(name)
|
28
|
+
cls.default_options unless cls.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
# Load the transport plugin indicated by name. If the plugin is not
|
32
|
+
# yet found in the plugin registry, it will be attempted to load from
|
33
|
+
# `train/transports/plugin_name`.
|
34
|
+
#
|
35
|
+
# @param [String] name of the plugin
|
36
|
+
# @return [Train::Transport] the transport plugin
|
37
|
+
def self.load_transport(name)
|
38
|
+
res = Train::Plugins.registry[name.to_s]
|
39
|
+
return res unless res.nil?
|
40
|
+
|
41
|
+
# if the plugin wasnt loaded yet:
|
42
|
+
require 'train/transports/' + name.to_s
|
43
|
+
Train::Plugins.registry[name.to_s]
|
44
|
+
rescue LoadError => _
|
45
|
+
raise Train::UserError,
|
46
|
+
"Can't find train plugin #{name.inspect}. Please install it first."
|
47
|
+
end
|
48
|
+
|
49
|
+
# Resolve target configuration in URI-scheme into
|
50
|
+
# all respective fields and merge with existing configuration.
|
51
|
+
# e.g. ssh://bob@remote => backend: ssh, user: bob, host: remote
|
52
|
+
def self.target_config(config = nil) # rubocop:disable Metrics/AbcSize
|
53
|
+
conf = config.nil? ? {} : config.dup
|
54
|
+
|
55
|
+
# symbolize keys
|
56
|
+
conf = conf.each_with_object({}) do |(k, v), acc|
|
57
|
+
acc[k.to_sym] = v
|
58
|
+
acc
|
59
|
+
end
|
60
|
+
|
61
|
+
group_keys_and_keyfiles(conf)
|
62
|
+
|
63
|
+
return conf if conf[:target].to_s.empty?
|
64
|
+
|
65
|
+
# split up the target's host/scheme configuration
|
66
|
+
uri = URI.parse(conf[:target].to_s)
|
67
|
+
unless uri.host.nil? and uri.scheme.nil?
|
68
|
+
conf[:backend] ||= uri.scheme
|
69
|
+
conf[:host] ||= uri.host
|
70
|
+
conf[:port] ||= uri.port
|
71
|
+
conf[:user] ||= uri.user
|
72
|
+
conf[:password] ||= uri.password
|
73
|
+
conf[:path] ||= uri.path
|
74
|
+
end
|
75
|
+
|
76
|
+
# ensure path is nil, if its empty; e.g. required to reset defaults for winrm
|
77
|
+
conf[:path] = nil if !conf[:path].nil? && conf[:path].to_s.empty?
|
78
|
+
|
79
|
+
# return the updated config
|
80
|
+
conf
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.validate_backend(conf, default = :local)
|
84
|
+
return default if conf.nil?
|
85
|
+
res = conf[:backend]
|
86
|
+
return res if !res.nil?
|
87
|
+
|
88
|
+
if !conf[:target].nil?
|
89
|
+
fail Train::UserError, 'Cannot determine backend from target '\
|
90
|
+
"configuration #{conf[:target].inspect}. Valid example: ssh://192.168.0.1."
|
91
|
+
end
|
92
|
+
|
93
|
+
if !conf[:host].nil?
|
94
|
+
fail Train::UserError, 'Host configured, but no backend was provided. Please '\
|
95
|
+
'specify how you want to connect. Valid example: ssh://192.168.0.1.'
|
96
|
+
end
|
97
|
+
|
98
|
+
conf[:backend] = default
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.group_keys_and_keyfiles(conf)
|
102
|
+
# in case the user specified a key-file, register it that way
|
103
|
+
# we will clear the list of keys and put keys and key_files separately
|
104
|
+
keys_mixed = conf[:keys]
|
105
|
+
return if keys_mixed.nil?
|
106
|
+
|
107
|
+
conf[:key_files] = []
|
108
|
+
conf[:keys] = []
|
109
|
+
keys_mixed.each do |key|
|
110
|
+
if !key.nil? and File.file?(key)
|
111
|
+
conf[:key_files].push(key)
|
112
|
+
else
|
113
|
+
conf[:keys].push(key)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/train/errors.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
+
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
5
|
+
# Author:: Christoph Hartmann (<chris@lollyrock.com>)
|
6
|
+
#
|
7
|
+
# Copyright (C) 2013, Fletcher Nichol
|
8
|
+
#
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
10
|
+
|
11
|
+
module Train
|
12
|
+
# Base exception class for all exceptions that are caused by user input
|
13
|
+
# errors.
|
14
|
+
class UserError < ::StandardError; end
|
15
|
+
|
16
|
+
# Base exception class for all exceptions that are caused by incorrect use
|
17
|
+
# of an API.
|
18
|
+
class ClientError < ::StandardError; end
|
19
|
+
|
20
|
+
# Base exception class for all exceptions that are caused by other failures
|
21
|
+
# in the transport layer.
|
22
|
+
class TransportError < ::StandardError; end
|
23
|
+
end
|
data/lib/train/extras.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
4
|
+
|
5
|
+
module Train::Extras
|
6
|
+
autoload :CommandWrapper, 'train/extras/command_wrapper'
|
7
|
+
autoload :FileCommon, 'train/extras/file_common'
|
8
|
+
autoload :AixFile, 'train/extras/file_aix'
|
9
|
+
autoload :UnixFile, 'train/extras/file_unix'
|
10
|
+
autoload :LinuxFile, 'train/extras/file_linux'
|
11
|
+
autoload :WindowsFile, 'train/extras/file_windows'
|
12
|
+
autoload :OSCommon, 'train/extras/os_common'
|
13
|
+
autoload :Stat, 'train/extras/stat'
|
14
|
+
|
15
|
+
CommandResult = Struct.new(:stdout, :stderr, :exit_status)
|
16
|
+
LoginCommand = Struct.new(:command, :arguments)
|
17
|
+
end
|