vcoworkflows 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +203 -0
- data/README.md +290 -0
- data/Rakefile +21 -0
- data/bin/vcoworkflows +7 -0
- data/example.rb +45 -0
- data/lib/vcoworkflows.rb +34 -0
- data/lib/vcoworkflows/cli/auth.rb +27 -0
- data/lib/vcoworkflows/cli/execute.rb +109 -0
- data/lib/vcoworkflows/cli/query.rb +106 -0
- data/lib/vcoworkflows/constants.rb +44 -0
- data/lib/vcoworkflows/runner.rb +44 -0
- data/lib/vcoworkflows/vcosession.rb +48 -0
- data/lib/vcoworkflows/version.rb +4 -0
- data/lib/vcoworkflows/workflow.rb +304 -0
- data/lib/vcoworkflows/workflowexecutionlog.rb +40 -0
- data/lib/vcoworkflows/workflowparameter.rb +145 -0
- data/lib/vcoworkflows/workflowpresentation.rb +59 -0
- data/lib/vcoworkflows/workflowservice.rb +110 -0
- data/lib/vcoworkflows/workflowtoken.rb +111 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/vcoworkflows/vcosession_spec.rb +33 -0
- data/spec/vcoworkflows/workflow_spec.rb +144 -0
- data/spec/vcoworkflows/workflowexecutionlog_spec.rb +22 -0
- data/spec/vcoworkflows/workflowparameter_spec.rb +67 -0
- data/spec/vcoworkflows/workflowpresentation_spec.rb +34 -0
- data/spec/vcoworkflows/workflowservice_spec.rb +113 -0
- data/spec/vcoworkflows/workflowtoken_spec.rb +64 -0
- data/vcoworkflows.gemspec +39 -0
- metadata +257 -0
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
require 'coveralls/rake/task'
|
5
|
+
require 'yard'
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
Cucumber::Rake::Task.new(:features)
|
10
|
+
Coveralls::RakeTask.new
|
11
|
+
|
12
|
+
task :style do
|
13
|
+
sh 'rubocop'
|
14
|
+
end
|
15
|
+
|
16
|
+
task :doc do
|
17
|
+
sh 'yard'
|
18
|
+
end
|
19
|
+
|
20
|
+
# task default: [:spec, :features, :style, :doc, 'coveralls:push']
|
21
|
+
task default: [:spec, :style, :doc, 'coveralls:push']
|
data/bin/vcoworkflows
ADDED
data/example.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'vcoworkflows'
|
4
|
+
|
5
|
+
# What am I connecting to?
|
6
|
+
url = 'https://myvco.example.com:8281/vco/api'
|
7
|
+
username = 'myuser'
|
8
|
+
password = 'secret!'
|
9
|
+
|
10
|
+
# What's the workflow I want to work with?
|
11
|
+
workflow_name = 'Do Something Cool'
|
12
|
+
|
13
|
+
# Define the parameters for the workflow which we need to supply.
|
14
|
+
# The 'Do Something Cool' workflow needs a name, version, and words (an array
|
15
|
+
# of strings).
|
16
|
+
input_parameters = { 'name' => 'a string value',
|
17
|
+
'version' => '2',
|
18
|
+
'words' => %w(fe fi fo fum) }
|
19
|
+
|
20
|
+
# Fetch the workflow from vCO
|
21
|
+
workflow = VcoWorkflows::Workflow.new(workflow_name,
|
22
|
+
url: url,
|
23
|
+
username: username,
|
24
|
+
password: password,
|
25
|
+
verify_ssl: false)
|
26
|
+
|
27
|
+
# Set the parameters in the workflow
|
28
|
+
input_parameters.each { |k, v| workflow.set_parameter(k, v) }
|
29
|
+
|
30
|
+
# Execute the workflow.
|
31
|
+
workflow.execute
|
32
|
+
|
33
|
+
# We're going to wait around until the execution is done, so we'll check
|
34
|
+
# on it every 5 seconds until we see whether it completed or failed.
|
35
|
+
finished = false
|
36
|
+
until finished
|
37
|
+
sleep 5
|
38
|
+
# Fetch a new workflow token to check the status of the workflow execution
|
39
|
+
wftoken = workflow.token
|
40
|
+
# If the execution is no longer alive, exit the loop and report the results.
|
41
|
+
unless wftoken.alive?
|
42
|
+
finished = true
|
43
|
+
wftoken.output_parameters.each { |k, v| puts " #{k}: #{v}" }
|
44
|
+
end
|
45
|
+
end
|
data/lib/vcoworkflows.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/vcoworkflows/version'
|
4
|
+
require File.dirname(__FILE__) + '/vcoworkflows/constants'
|
5
|
+
require File.dirname(__FILE__) + '/vcoworkflows/vcosession'
|
6
|
+
require File.dirname(__FILE__) + '/vcoworkflows/workflowservice'
|
7
|
+
require File.dirname(__FILE__) + '/vcoworkflows/workflow'
|
8
|
+
require File.dirname(__FILE__) + '/vcoworkflows/workflowparameter'
|
9
|
+
require File.dirname(__FILE__) + '/vcoworkflows/workflowtoken'
|
10
|
+
require File.dirname(__FILE__) + '/vcoworkflows/cli/execute'
|
11
|
+
require File.dirname(__FILE__) + '/vcoworkflows/cli/query'
|
12
|
+
|
13
|
+
# rubocop:disable LineLength
|
14
|
+
|
15
|
+
# Refer to README.md for use instructions
|
16
|
+
module VcoWorkflows
|
17
|
+
# Start of main CLI processing
|
18
|
+
class CLI < Thor
|
19
|
+
package_name 'vcoworkflows'
|
20
|
+
map '--version' => :version
|
21
|
+
map '-v' => :version
|
22
|
+
|
23
|
+
desc 'version', DESC_VERSION
|
24
|
+
|
25
|
+
# Display the version of `vcoworkflows`
|
26
|
+
def version
|
27
|
+
puts VERSION
|
28
|
+
end
|
29
|
+
|
30
|
+
register(VcoWorkflows::Cli::Execute, 'execute', 'execute <WORKFLOW>', DESC_CLI_EXECUTE)
|
31
|
+
register(VcoWorkflows::Cli::Query, 'query', 'query <WORKFLOW>', DESC_CLI_QUERY)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
# rubocop:enable LineLength
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'vcoworkflows/constants'
|
2
|
+
|
3
|
+
# VcoWorkflows
|
4
|
+
module VcoWorkflows
|
5
|
+
# Cli
|
6
|
+
module Cli
|
7
|
+
# Auth
|
8
|
+
class Auth
|
9
|
+
attr_reader :username
|
10
|
+
attr_reader :password
|
11
|
+
|
12
|
+
# Initialize the Auth object
|
13
|
+
# @param [String] username
|
14
|
+
# @param [String] password
|
15
|
+
def initialize(username: nil, password: nil)
|
16
|
+
# Set username and password from parameters, if provided, or
|
17
|
+
# environment variables $VCO_USER and $VCO_PASSWD, if not.
|
18
|
+
@username = username.nil? ? ENV['VCO_USER'] : username
|
19
|
+
@password = password.nil? ? ENV['VCO_PASSWD'] : password
|
20
|
+
|
21
|
+
# Fail if we don't have both a username and a password.
|
22
|
+
fail(IOError, ERR[:username_unset]) if @username.nil?
|
23
|
+
fail(IOError, ERR[:password_unset]) if @password.nil?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'vcoworkflows'
|
2
|
+
require_relative 'auth'
|
3
|
+
require 'thor/group'
|
4
|
+
|
5
|
+
# rubocop:disable MethodLength, LineLength
|
6
|
+
|
7
|
+
# VcoWorkflows
|
8
|
+
module VcoWorkflows
|
9
|
+
# Cli
|
10
|
+
module Cli
|
11
|
+
# Execute
|
12
|
+
class Execute < Thor::Group
|
13
|
+
include Thor::Actions
|
14
|
+
|
15
|
+
argument :workflow, type: :string, desc: DESC_CLI_WORKFLOW
|
16
|
+
class_option :server, type: :string, aliases: '-s', required: true, desc: DESC_CLI_SERVER
|
17
|
+
class_option :username, type: :string, aliases: '-u', desc: DESC_CLI_USERNAME
|
18
|
+
class_option :password, type: :string, aliases: '-p', desc: DESC_CLI_PASSWORD
|
19
|
+
class_option :id, type: :string, aliases: '-i', desc: DESC_CLI_WORKFLOW_ID
|
20
|
+
class_option :verify_ssl, type: :boolean, default: true, desc: DESC_CLI_VERIFY_SSL
|
21
|
+
class_option :dry_run, type: :boolean, default: false, desc: DESC_CLI_DRY_RUN
|
22
|
+
class_option :verbose, type: :boolean, default: true, desc: DESC_CLI_VERBOSE
|
23
|
+
class_option :watch, type: :boolean, default: true, desc: DESC_CLI_EXECUTE_WATCH
|
24
|
+
|
25
|
+
class_option :parameters, type: :string, required: true, desc: DESC_CLI_EXECUTE_PARAMETERS
|
26
|
+
|
27
|
+
def self.source_root
|
28
|
+
File.dirname(__FILE__)
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:disable CyclomaticComplexity, PerceivedComplexity
|
32
|
+
def execute
|
33
|
+
auth = VcoWorkflows::Cli::Auth.new(username: options[:username], password: options[:password])
|
34
|
+
|
35
|
+
# Parse out the parameters
|
36
|
+
parameters = {}
|
37
|
+
options[:parameters].split(/,/).each do |p|
|
38
|
+
k, v = p.split(/=/)
|
39
|
+
parameters[k] = v
|
40
|
+
end
|
41
|
+
if parameters.key?('runlist')
|
42
|
+
parameters['runlist'] = parameters['runlist'].split(/:/)
|
43
|
+
end
|
44
|
+
|
45
|
+
puts "Executing against vCO REST endpoint: #{options[:server]}"
|
46
|
+
puts "Requested execution of workflow: '#{workflow}'"
|
47
|
+
puts "Will call workflow by GUID (#{options[:id]})" if options[:id]
|
48
|
+
if options[:verbose] || options[:dry_run]
|
49
|
+
puts 'Parameters:'
|
50
|
+
parameters.each do |k, v|
|
51
|
+
v = v.join(',') if v.is_a?(Array)
|
52
|
+
puts " - #{k}: #{v}"
|
53
|
+
end
|
54
|
+
puts ''
|
55
|
+
end
|
56
|
+
|
57
|
+
return if options[:dry_run]
|
58
|
+
|
59
|
+
# Get the workflow
|
60
|
+
puts "Retrieving workflow '#{workflow}' ..."
|
61
|
+
wf = VcoWorkflows::Workflow.new(workflow,
|
62
|
+
url: options[:server],
|
63
|
+
username: auth.username,
|
64
|
+
password: auth.password,
|
65
|
+
verify_ssl: options[:verify_ssl],
|
66
|
+
id: options[:id])
|
67
|
+
|
68
|
+
# List out mandatory parameters
|
69
|
+
puts "Required parameters:\n #{wf.required_parameters.keys.join(', ')}"
|
70
|
+
|
71
|
+
# Set the input parameters
|
72
|
+
puts 'Setting workflow input parameters...' if options[:verbose]
|
73
|
+
parameters.each do |k, v|
|
74
|
+
puts "setting #{k} to #{v}" if options[:verbose]
|
75
|
+
wf.set_parameter(k, v)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Execute the workflow
|
79
|
+
puts 'Executing workflow...'
|
80
|
+
wf.execute
|
81
|
+
|
82
|
+
# Fetch the results
|
83
|
+
wftoken = wf.token
|
84
|
+
puts "#{wftoken.id} started at #{Time.at(wftoken.start_date / 1000)}"
|
85
|
+
|
86
|
+
# If we don't care about the results, move on.
|
87
|
+
return unless options[:watch]
|
88
|
+
|
89
|
+
# Check for update results until we get one who's state
|
90
|
+
# is not "running" or "waiting"
|
91
|
+
puts "\nChecking status...\n"
|
92
|
+
while wftoken.alive?
|
93
|
+
sleep 10
|
94
|
+
wftoken = wf.token
|
95
|
+
puts "#{Time.now} state: #{wftoken.state}"
|
96
|
+
end
|
97
|
+
puts "\nFinal status of execution:"
|
98
|
+
puts wftoken
|
99
|
+
|
100
|
+
# Print out the execution log
|
101
|
+
puts "\nWorkflow #{wf.name} log for execution #{wftoken.id}:"
|
102
|
+
log = wf.log(wftoken.id)
|
103
|
+
puts "\n#{log}"
|
104
|
+
end
|
105
|
+
# rubocop:enable CyclomaticComplexity, PerceivedComplexity
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
# rubocop:enable MethodLength, LineLength
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'vcoworkflows'
|
2
|
+
require_relative 'auth'
|
3
|
+
require 'thor/group'
|
4
|
+
|
5
|
+
# rubocop:disable MethodLength, LineLength
|
6
|
+
|
7
|
+
# VcoWorkflows
|
8
|
+
module VcoWorkflows
|
9
|
+
# Cli
|
10
|
+
module Cli
|
11
|
+
# Query
|
12
|
+
class Query < Thor::Group
|
13
|
+
include Thor::Actions
|
14
|
+
|
15
|
+
argument :workflow, type: :string, desc: DESC_CLI_WORKFLOW
|
16
|
+
class_option :server, type: :string, aliases: '-s', required: true, desc: DESC_CLI_SERVER
|
17
|
+
class_option :username, type: :string, aliases: '-u', desc: DESC_CLI_USERNAME
|
18
|
+
class_option :password, type: :string, aliases: '-p', desc: DESC_CLI_PASSWORD
|
19
|
+
class_option :id, type: :string, aliases: '-i', desc: DESC_CLI_WORKFLOW_ID
|
20
|
+
class_option :verify_ssl, type: :boolean, default: true, desc: DESC_CLI_VERIFY_SSL
|
21
|
+
class_option :dry_run, type: :boolean, default: false, desc: DESC_CLI_DRY_RUN
|
22
|
+
|
23
|
+
class_option :executions, type: :boolean, aliases: '-e', default: false, desc: DESC_CLI_QUERY_EXECS
|
24
|
+
class_option :last, type: :numeric, aliases: '-l', default: 0, desc: DESC_CLI_QUERY_EXEC_LIM
|
25
|
+
class_option :execution_id, type: :string, aliases: ['-I', '--execution'], desc: DESC_CLI_QUERY_EXEC_ID
|
26
|
+
class_option :state, type: :boolean, aliases: '-r', desc: DESC_CLI_QUERY_EXEC_STATE
|
27
|
+
class_option :logs, type: :boolean, aliases: ['-L', '--log'], desc: DESC_CLI_QUERY_EXEC_LOG
|
28
|
+
class_option :show_json, type: :boolean, default: false, desc: DESC_CLI_QUERY_JSON
|
29
|
+
|
30
|
+
def self.source_root
|
31
|
+
File.dirname(__FILE__)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Process the subcommand
|
35
|
+
# rubocop:disable CyclomaticComplexity, PerceivedComplexity
|
36
|
+
def query
|
37
|
+
auth = VcoWorkflows::Cli::Auth.new(username: options[:username], password: options[:password])
|
38
|
+
|
39
|
+
if options[:dry_run]
|
40
|
+
puts "\nQuerying against vCO REST endpoint:\n #{options[:server]}"
|
41
|
+
puts "Will search for workflow: '#{workflow}'"
|
42
|
+
puts "Will query workflow by GUID (#{options[:id]})" if options[:id]
|
43
|
+
return
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get the workflow
|
47
|
+
puts "\nRetrieving workflow '#{workflow}' ..."
|
48
|
+
wf = VcoWorkflows::Workflow.new(workflow,
|
49
|
+
url: options[:server],
|
50
|
+
username: auth.username,
|
51
|
+
password: auth.password,
|
52
|
+
verify_ssl: options[:verify_ssl],
|
53
|
+
id: options[:id])
|
54
|
+
|
55
|
+
puts ''
|
56
|
+
if options[:execution_id]
|
57
|
+
puts "Fetching data for execution #{options[:execution_id]}..."
|
58
|
+
execution = wf.token(options[:execution_id])
|
59
|
+
if options[:state]
|
60
|
+
puts "Execution started at #{Time.at(execution.start_date / 1000)}"
|
61
|
+
puts "Execution #{execution.state} at #{Time.at(execution.end_date / 1000)}"
|
62
|
+
else
|
63
|
+
puts ''
|
64
|
+
if options[:show_json]
|
65
|
+
puts execution.to_json
|
66
|
+
else
|
67
|
+
puts execution
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
if options[:logs]
|
72
|
+
puts ''
|
73
|
+
wflog = wf.log(options[:execution_id])
|
74
|
+
if options[:show_json]
|
75
|
+
puts wflog.to_json
|
76
|
+
else
|
77
|
+
puts wflog
|
78
|
+
end
|
79
|
+
end
|
80
|
+
else
|
81
|
+
puts wf unless options[:executions]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Last thing we're checking for, so if it's not wanted, just return
|
85
|
+
return unless options[:executions]
|
86
|
+
puts "\nWorkflow: #{wf.name}"
|
87
|
+
puts "ID: #{wf.id}"
|
88
|
+
puts "Description: #{wf.description}"
|
89
|
+
puts "Version: #{wf.version}"
|
90
|
+
puts "\nExecutions: "
|
91
|
+
executions = {}
|
92
|
+
wf.executions.each_value { |attrs| executions[attrs['startDate']] = attrs }
|
93
|
+
keys = executions.keys.sort
|
94
|
+
keys = keys.slice(keys.size - options[:last], keys.size) if options[:last] > 0
|
95
|
+
keys.each do |timestamp|
|
96
|
+
dataline = "#{timestamp}"
|
97
|
+
dataline << " [#{executions[timestamp]['id']}]"
|
98
|
+
dataline << " #{executions[timestamp]['state']}"
|
99
|
+
puts dataline
|
100
|
+
end
|
101
|
+
end
|
102
|
+
# rubocop:enable CyclomaticComplexity, PerceivedComplexity
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# rubocop:enable MethodLength, LineLength
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# VcoWorkflows
|
2
|
+
module VcoWorkflows
|
3
|
+
# rubocop:disable LineLength
|
4
|
+
|
5
|
+
# Options description messages
|
6
|
+
DESC_VERSION = 'Display the installed version of the VcoWorkflows gem'
|
7
|
+
DESC_CLI_EXECUTE = 'Execute the specified workflow'
|
8
|
+
DESC_CLI_QUERY = 'Query vCO for a workflow'
|
9
|
+
DESC_CLI_WORKFLOW = 'Name of the workflow'
|
10
|
+
DESC_CLI_WORKFLOW_ID = 'GUID of the workflow'
|
11
|
+
DESC_CLI_DRY_RUN = 'Dry run; do not actually perform operations against vCO'
|
12
|
+
DESC_CLI_VERBOSE = 'Show extra information'
|
13
|
+
DESC_CLI_NAME = 'Name of the workflow to execute'
|
14
|
+
DESC_CLI_SERVER = 'VMware vCenter Orchestrator server URL'
|
15
|
+
DESC_CLI_USERNAME = 'vCO user name'
|
16
|
+
DESC_CLI_PASSWORD = 'vCO password'
|
17
|
+
DESC_CLI_VERIFY_SSL = 'Perform TSL Certificate verification'
|
18
|
+
DESC_CLI_EXECUTE_WATCH = 'Wait around for workflow results'
|
19
|
+
DESC_CLI_EXECUTE_PARAMETERS = 'Comma-separated list of key=value parameters for workflow'
|
20
|
+
DESC_CLI_QUERY_EXECS = 'Fetch a list of executions for the workflow'
|
21
|
+
DESC_CLI_QUERY_EXEC_LIM = 'Limit the number of returned executions to the most recent N'
|
22
|
+
DESC_CLI_QUERY_EXEC_ID = 'Fetch the execution data for this execution GUID'
|
23
|
+
DESC_CLI_QUERY_EXEC_STATE = 'Fetch the state of the specified workflow execution'
|
24
|
+
DESC_CLI_QUERY_EXEC_LOG = 'In addition to execution data, show the execution log'
|
25
|
+
DESC_CLI_QUERY_JSON = 'Show the JSON document for the requested information'
|
26
|
+
|
27
|
+
# What do all the vCO REST URIs start with?
|
28
|
+
API_URL_BASE = '/vco/api'
|
29
|
+
|
30
|
+
# error messages
|
31
|
+
ERR = {
|
32
|
+
wtf: 'vcoworkflows: I have no idea what just went wrong.',
|
33
|
+
no_workflow_found: 'vcoworkflows: no workflow found!',
|
34
|
+
too_many_workflows: 'vcoworkflows: more than one workflow found for given name!',
|
35
|
+
wrong_workflow_wtf: 'vcoworkflows: search returned the wrong workflow! (?)',
|
36
|
+
no_workflow_service_defined: 'vcoworkflows: Attempted to execute a workflow with a nil workflow service!',
|
37
|
+
param_verify_failed: 'vcoworkflows: Attempt to verify required parameter failed!',
|
38
|
+
no_such_parameter: 'Attempted to set a parameter that does not exist!',
|
39
|
+
username_unset: 'No username was specified, either by $VCO_USER or --username',
|
40
|
+
password_unset: 'No password was specified, either by $VCO_PASSWD or --password'
|
41
|
+
}
|
42
|
+
|
43
|
+
# rubocop:enable LineLength
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'vcoworkflows'
|
2
|
+
|
3
|
+
# rubocop:disable all
|
4
|
+
module VcoWorkflows
|
5
|
+
# wrapper to assist aruba in single process execution
|
6
|
+
class Runner
|
7
|
+
# Allow everything fun to be injected from the outside while defaulting to normal implementations.
|
8
|
+
def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
|
9
|
+
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
10
|
+
end
|
11
|
+
|
12
|
+
# Do the things!
|
13
|
+
def execute!
|
14
|
+
exit_code = begin
|
15
|
+
# Thor accesses these streams directly rather than letting them be
|
16
|
+
# injected, so we replace them...
|
17
|
+
$stderr = @stderr
|
18
|
+
$stdin = @stdin
|
19
|
+
$stdout = @stdout
|
20
|
+
|
21
|
+
VcoWorkflows::CLI.start(@argv)
|
22
|
+
|
23
|
+
# Thor::Base#start does not have a return value, assume success if no
|
24
|
+
# exception is raised.
|
25
|
+
0
|
26
|
+
rescue StandardError => e
|
27
|
+
# The ruby interpreter would pipe this to STDERR and exit 1 in the
|
28
|
+
# case of an unhandled exception
|
29
|
+
b = e.backtrace
|
30
|
+
b.unshift("#{b.shift}: #{e.message} (#{e.class})")
|
31
|
+
@stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
|
32
|
+
1
|
33
|
+
ensure
|
34
|
+
# put them back.
|
35
|
+
$stderr = STDERR
|
36
|
+
$stdin = STDIN
|
37
|
+
$stdout = STDOUT
|
38
|
+
end
|
39
|
+
# Proxy exit code back to the injected kernel.
|
40
|
+
@kernel.exit(exit_code)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# rubocop:enable all
|