floe 0.18.0 → 0.19.0
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 +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +25 -2
- data/examples/log.asl +33 -0
- data/lib/floe/builtin_runner/methods.rb +29 -0
- data/lib/floe/container_runner/docker.rb +9 -2
- data/lib/floe/container_runner/kubernetes.rb +3 -0
- data/lib/floe/version.rb +1 -1
- data/lib/floe/workflow/context.rb +13 -0
- data/lib/floe/workflow/state.rb +5 -3
- data/lib/floe/workflow/states/task.rb +62 -24
- data/lib/floe/workflow.rb +2 -10
- data/lib/floe.rb +19 -0
- metadata +2 -3
- data/.codeclimate.yml +0 -36
- data/.rubocop_cc.yml +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d7ec87295c6283b53c25c1791a9f8a2a953e48bec4059bf67fd5487875c114ce
|
|
4
|
+
data.tar.gz: a56a431253dd0a4a4c4470363ce0dfa83aa6f8ec834239a43266c6e41ccc0b61
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3d888a3713b5e3291e9fb7a04ea3254268e2ee11ccdc1a49af71f992cab61d5752d689f70292d67f3c9d3b69f146c47c0a86423a424c18220e813c2997c4402
|
|
7
|
+
data.tar.gz: f54adf8264d7ed09c05d2c78b8f5029d0ed5c472ac365e75a3656cc66fa29db0dd79eded1136b0893114d75eaf9a5e4637e76a2c347d1b8917ac8d3cf4238ec2
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.19.0] - 2025-12-16
|
|
8
|
+
### Fixed
|
|
9
|
+
- Fix builtin_runner/runner spec file name ([#329](https://github.com/ManageIQ/floe/pull/329))
|
|
10
|
+
- Check WaitUntil before starting a State ([#336](https://github.com/ManageIQ/floe/pull/336))
|
|
11
|
+
- Task TimeoutSeconds and TimeoutSecondsPath not implemented ([#330](https://github.com/ManageIQ/floe/pull/330))
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Add floe://log builtin method ([#328](https://github.com/ManageIQ/floe/pull/328))
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Raise `States.Timeout` in `running?` and remove duplicate `timed_out?` check in `finished?` ([#337](https://github.com/ManageIQ/floe/pull/337))
|
|
18
|
+
|
|
7
19
|
## [0.18.0] - 2025-10-24
|
|
8
20
|
### Added
|
|
9
21
|
- Declare active support dependency ([#316](https://github.com/ManageIQ/floe/pull/316))
|
|
@@ -317,7 +329,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
317
329
|
### Added
|
|
318
330
|
- Initial release
|
|
319
331
|
|
|
320
|
-
[Unreleased]: https://github.com/ManageIQ/floe/compare/v0.
|
|
332
|
+
[Unreleased]: https://github.com/ManageIQ/floe/compare/v0.19.0...HEAD
|
|
333
|
+
[0.19.0]: https://github.com/ManageIQ/floe/compare/v0.18.0...v0.19.0
|
|
321
334
|
[0.18.0]: https://github.com/ManageIQ/floe/compare/v0.17.1...v0.18.0
|
|
322
335
|
[0.17.1]: https://github.com/ManageIQ/floe/compare/v0.17.0...v0.17.1
|
|
323
336
|
[0.17.0]: https://github.com/ManageIQ/floe/compare/v0.16.0...v0.17.0
|
data/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# Floe
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ManageIQ/floe/actions/workflows/ci.yaml)
|
|
4
|
-
[](https://codeclimate.com/github/ManageIQ/floe)
|
|
5
|
-
[](https://codeclimate.com/github/ManageIQ/floe/coverage)
|
|
6
4
|
|
|
7
5
|
## Overview
|
|
8
6
|
|
|
@@ -167,6 +165,31 @@ Task Runner Types:
|
|
|
167
165
|
|
|
168
166
|
This is the "builtin" runner and exposes methods that are executed internally without having to call out to a docker image.
|
|
169
167
|
|
|
168
|
+
##### Log builtin method
|
|
169
|
+
|
|
170
|
+
`floe://log` allows you to write a message to the logger.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"Comment": "Print log message",
|
|
176
|
+
"StartAt": "Log",
|
|
177
|
+
"States": {
|
|
178
|
+
"Log": {
|
|
179
|
+
"Type": "Task",
|
|
180
|
+
"Resource": "floe://log",
|
|
181
|
+
"Parameters": {
|
|
182
|
+
"Level": "INFO",
|
|
183
|
+
"Message": "Hello, Floe!"
|
|
184
|
+
},
|
|
185
|
+
"End": true
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Log Parameters:
|
|
190
|
+
* `Level` (required) - Log level. Permitted values: `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, or `UNKNOWN`. Defaults to `INFO`.
|
|
191
|
+
* `Message` (required) - The message to log
|
|
192
|
+
|
|
170
193
|
##### HTTP builtin method
|
|
171
194
|
|
|
172
195
|
`floe://http` allows you to execute HTTP method calls.
|
data/examples/log.asl
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "Print log messages",
|
|
3
|
+
"StartAt": "Log Info",
|
|
4
|
+
"States": {
|
|
5
|
+
"Log Info": {
|
|
6
|
+
"Type": "Task",
|
|
7
|
+
"Resource": "floe://log",
|
|
8
|
+
"Parameters": {
|
|
9
|
+
"Level": "INFO",
|
|
10
|
+
"Message": "Hello, Floe!"
|
|
11
|
+
},
|
|
12
|
+
"Next": "Log Debug"
|
|
13
|
+
},
|
|
14
|
+
"Log Debug": {
|
|
15
|
+
"Type": "Task",
|
|
16
|
+
"Resource": "floe://log",
|
|
17
|
+
"Parameters": {
|
|
18
|
+
"Level": "DEBUG",
|
|
19
|
+
"Message": "Hello, Floe!"
|
|
20
|
+
},
|
|
21
|
+
"Next": "Log From Input"
|
|
22
|
+
},
|
|
23
|
+
"Log From Input": {
|
|
24
|
+
"Type": "Task",
|
|
25
|
+
"Resource": "floe://log",
|
|
26
|
+
"Parameters": {
|
|
27
|
+
"Level": "INFO",
|
|
28
|
+
"Message.$": "States.Format('Hello, {}!', $.name)"
|
|
29
|
+
},
|
|
30
|
+
"End": true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,6 +1,35 @@
|
|
|
1
|
+
require "logger"
|
|
2
|
+
|
|
1
3
|
module Floe
|
|
2
4
|
module BuiltinRunner
|
|
3
5
|
class Methods < BasicObject
|
|
6
|
+
def self.log(params, _secrets, context)
|
|
7
|
+
params["Level"] = (params["Level"] ||= "INFO").upcase
|
|
8
|
+
|
|
9
|
+
error = log_verify_params(params)
|
|
10
|
+
return BuiltinRunner.error!({}, :cause => error) if error
|
|
11
|
+
|
|
12
|
+
level, message = params.values_at("Level", "Message")
|
|
13
|
+
|
|
14
|
+
context.logger.add(::Logger::Severity.const_get(level), message)
|
|
15
|
+
|
|
16
|
+
BuiltinRunner.success!({}, :output => context.input)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
LOG_SEVERITIES = ::Logger::Severity.constants.sort_by { |s| ::Logger::Severity.const_get(s) }.map(&:to_s)
|
|
20
|
+
LOG_SEVERITIES_S = "#{LOG_SEVERITIES[0..-2].join(", ")}, or #{LOG_SEVERITIES[-1]}"
|
|
21
|
+
|
|
22
|
+
private_class_method def self.log_verify_params(params)
|
|
23
|
+
return "Missing Parameter: Message" if params["Message"].nil?
|
|
24
|
+
return "Invalid Parameter: Level: [#{params["Level"]}], must be one of #{LOG_SEVERITIES_S}" unless LOG_SEVERITIES.include?(params["Level"])
|
|
25
|
+
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private_class_method def self.log_status!(runner_context)
|
|
30
|
+
runner_context
|
|
31
|
+
end
|
|
32
|
+
|
|
4
33
|
def self.http(params, _secrets, _context)
|
|
5
34
|
params["Method"] ||= "GET"
|
|
6
35
|
|
|
@@ -105,10 +105,14 @@ module Floe
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
def running?(runner_context)
|
|
108
|
+
return false if runner_context.key?("Error")
|
|
109
|
+
|
|
108
110
|
!!runner_context.dig("container_state", "Running")
|
|
109
111
|
end
|
|
110
112
|
|
|
111
113
|
def success?(runner_context)
|
|
114
|
+
return false if runner_context.key?("Error")
|
|
115
|
+
|
|
112
116
|
runner_context.dig("container_state", "ExitCode") == 0
|
|
113
117
|
end
|
|
114
118
|
|
|
@@ -186,8 +190,11 @@ module Floe
|
|
|
186
190
|
raise Floe::ExecutionError, "Failed to get status for container #{container_id}: #{err}"
|
|
187
191
|
end
|
|
188
192
|
|
|
189
|
-
def delete_container(container_id)
|
|
190
|
-
|
|
193
|
+
def delete_container(container_id, force: true)
|
|
194
|
+
params = ["rm", container_id]
|
|
195
|
+
params << "--force" if force
|
|
196
|
+
|
|
197
|
+
docker!(*params)
|
|
191
198
|
rescue
|
|
192
199
|
nil
|
|
193
200
|
end
|
|
@@ -70,6 +70,7 @@ module Floe
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def running?(runner_context)
|
|
73
|
+
return false if runner_context.key?("Error")
|
|
73
74
|
return false unless pod_running?(runner_context)
|
|
74
75
|
# If a pod is Pending and the containers are waiting with a failure
|
|
75
76
|
# reason such as ImagePullBackOff or CrashLoopBackOff then the pod
|
|
@@ -80,6 +81,8 @@ module Floe
|
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
def success?(runner_context)
|
|
84
|
+
return false if runner_context.key?("Error")
|
|
85
|
+
|
|
83
86
|
runner_context.dig("container_state", "phase") == "Succeeded"
|
|
84
87
|
end
|
|
85
88
|
|
data/lib/floe/version.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "securerandom"
|
|
4
|
+
|
|
3
5
|
module Floe
|
|
4
6
|
class Workflow
|
|
5
7
|
class Context
|
|
@@ -25,6 +27,17 @@ module Floe
|
|
|
25
27
|
raise Floe::InvalidExecutionInput, "Invalid State Machine Execution Input: #{err}: was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')"
|
|
26
28
|
end
|
|
27
29
|
|
|
30
|
+
def prepare_start(start_at)
|
|
31
|
+
return if started?
|
|
32
|
+
|
|
33
|
+
state["Name"] = start_at
|
|
34
|
+
state["Input"] = execution["Input"].dup
|
|
35
|
+
state["Guid"] = SecureRandom.uuid
|
|
36
|
+
|
|
37
|
+
execution["Id"] ||= SecureRandom.uuid
|
|
38
|
+
execution["StartTime"] = Time.now.utc.iso8601
|
|
39
|
+
end
|
|
40
|
+
|
|
28
41
|
def execution
|
|
29
42
|
@context["Execution"]
|
|
30
43
|
end
|
data/lib/floe/workflow/state.rb
CHANGED
|
@@ -43,7 +43,9 @@ module Floe
|
|
|
43
43
|
|
|
44
44
|
# @return for incomplete Errno::EAGAIN, for completed 0
|
|
45
45
|
def run_nonblock!(context)
|
|
46
|
-
start
|
|
46
|
+
# Only start the state if it isn't already started and it isn't waiting
|
|
47
|
+
# from a prior Retry.
|
|
48
|
+
start(context) unless started?(context) || waiting?(context)
|
|
47
49
|
return Errno::EAGAIN unless ready?(context)
|
|
48
50
|
|
|
49
51
|
finish(context)
|
|
@@ -89,13 +91,13 @@ module Floe
|
|
|
89
91
|
def mark_error(context, exception)
|
|
90
92
|
# InputPath or OutputPath were bad.
|
|
91
93
|
context.next_state = nil
|
|
92
|
-
context.output =
|
|
94
|
+
context.output = exception.to_output
|
|
93
95
|
# Since finish threw an exception, super was never called. Calling that now.
|
|
94
96
|
mark_finished(context)
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
def ready?(context)
|
|
98
|
-
|
|
100
|
+
(started?(context) && !running?(context)) || !waiting?(context)
|
|
99
101
|
end
|
|
100
102
|
|
|
101
103
|
def running?(context)
|
|
@@ -9,29 +9,29 @@ module Floe
|
|
|
9
9
|
include RetryCatchMixin
|
|
10
10
|
|
|
11
11
|
attr_reader :credentials, :end, :heartbeat_seconds, :next, :parameters,
|
|
12
|
-
:result_selector, :resource, :timeout_seconds, :
|
|
13
|
-
:input_path, :output_path, :result_path
|
|
12
|
+
:result_selector, :resource, :timeout_seconds, :timeout_seconds_path,
|
|
13
|
+
:retry, :catch, :input_path, :output_path, :result_path
|
|
14
14
|
|
|
15
15
|
def initialize(workflow, name, payload)
|
|
16
16
|
super
|
|
17
17
|
|
|
18
|
-
@
|
|
19
|
-
@next = payload["Next"]
|
|
20
|
-
@end = !!payload["End"]
|
|
21
|
-
@resource = payload["Resource"]
|
|
22
|
-
|
|
18
|
+
@resource = payload["Resource"]
|
|
23
19
|
missing_field_error!("Resource") unless @resource.kind_of?(String)
|
|
24
20
|
@runner = wrap_parser_error("Resource", @resource) { Floe::Runner.for_resource(@resource) }
|
|
25
21
|
|
|
26
|
-
@
|
|
27
|
-
@
|
|
28
|
-
@
|
|
29
|
-
@
|
|
30
|
-
@
|
|
31
|
-
@
|
|
32
|
-
@
|
|
33
|
-
@
|
|
34
|
-
@
|
|
22
|
+
@next = payload["Next"]
|
|
23
|
+
@end = !!payload["End"]
|
|
24
|
+
@timeout_seconds = payload["TimeoutSeconds"]
|
|
25
|
+
@heartbeat_seconds = payload["HeartbeatSeconds"]
|
|
26
|
+
@retry = payload["Retry"].to_a.map.with_index { |retrier, i| Retrier.new(workflow, name + ["Retry", i.to_s], retrier) }
|
|
27
|
+
@catch = payload["Catch"].to_a.map.with_index { |catcher, i| Catcher.new(workflow, name + ["Catch", i.to_s], catcher) }
|
|
28
|
+
@input_path = Path.new(payload.fetch("InputPath", "$"))
|
|
29
|
+
@output_path = Path.new(payload.fetch("OutputPath", "$"))
|
|
30
|
+
@result_path = ReferencePath.new(payload.fetch("ResultPath", "$"))
|
|
31
|
+
@timeout_seconds_path = ReferencePath.new(payload["TimeoutSecondsPath"]) if payload["TimeoutSecondsPath"]
|
|
32
|
+
@parameters = PayloadTemplate.new(payload["Parameters"]) if payload["Parameters"]
|
|
33
|
+
@result_selector = PayloadTemplate.new(payload["ResultSelector"]) if payload["ResultSelector"]
|
|
34
|
+
@credentials = PayloadTemplate.new(payload["Credentials"]) if payload["Credentials"]
|
|
35
35
|
|
|
36
36
|
validate_state!(workflow)
|
|
37
37
|
end
|
|
@@ -39,6 +39,9 @@ module Floe
|
|
|
39
39
|
def start(context)
|
|
40
40
|
super
|
|
41
41
|
|
|
42
|
+
# Wakeup no later than timeout_seconds to check if the Resource has timed out
|
|
43
|
+
wait_until!(context, :seconds => timeout_seconds) if timeout_seconds
|
|
44
|
+
|
|
42
45
|
input = process_input(context)
|
|
43
46
|
secrets = credentials&.value(context, context.input)
|
|
44
47
|
runner_context = runner.run_async!(resource, input, secrets, context)
|
|
@@ -48,27 +51,31 @@ module Floe
|
|
|
48
51
|
|
|
49
52
|
def finish(context)
|
|
50
53
|
output = runner.output(context.state["RunnerContext"])
|
|
54
|
+
raise Floe::ExecutionError.from_output(parse_error(output)) unless success?(context)
|
|
55
|
+
|
|
56
|
+
output = parse_output(output)
|
|
57
|
+
context.output = process_output(context, output)
|
|
51
58
|
|
|
52
|
-
if success?(context)
|
|
53
|
-
output = parse_output(output)
|
|
54
|
-
context.output = process_output(context, output)
|
|
55
|
-
else
|
|
56
|
-
error = parse_error(output)
|
|
57
|
-
retry_state!(context, error) || catch_error!(context, error) || fail_workflow!(context, error)
|
|
58
|
-
end
|
|
59
59
|
super
|
|
60
60
|
ensure
|
|
61
61
|
runner.cleanup(context.state["RunnerContext"])
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def running?(context)
|
|
65
|
-
|
|
65
|
+
raise Floe::TimeoutError if timed_out?(context)
|
|
66
66
|
return false if finished?(context)
|
|
67
67
|
|
|
68
68
|
runner.status!(context.state["RunnerContext"])
|
|
69
69
|
runner.running?(context.state["RunnerContext"])
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
def mark_error(context, exception)
|
|
73
|
+
error = exception.to_output
|
|
74
|
+
|
|
75
|
+
retry_state!(context, error) || catch_error!(context, error) || fail_workflow!(context, error)
|
|
76
|
+
mark_finished(context)
|
|
77
|
+
end
|
|
78
|
+
|
|
72
79
|
def end?
|
|
73
80
|
@end
|
|
74
81
|
end
|
|
@@ -79,12 +86,43 @@ module Floe
|
|
|
79
86
|
|
|
80
87
|
def validate_state!(workflow)
|
|
81
88
|
validate_state_next!(workflow)
|
|
89
|
+
validate_state_timeout_seconds!(workflow)
|
|
90
|
+
validate_state_timeout_seconds_path!(workflow)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def validate_state_timeout_seconds!(workflow)
|
|
94
|
+
return if @timeout_seconds.nil?
|
|
95
|
+
return if @timeout_seconds.kind_of?(Integer) && @timeout_seconds > 0
|
|
96
|
+
|
|
97
|
+
invalid_field_error!("TimeoutSeconds", @timeout_seconds, "must be positive, non-zero integer")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def validate_state_timeout_seconds_path!(workflow)
|
|
101
|
+
return if @timeout_seconds_path.nil? || @timeout_seconds.nil?
|
|
102
|
+
|
|
103
|
+
invalid_field_error!("TimeoutSecondsPath", nil, "cannot specify both \"TimeoutSeconds\" and \"TimeoutSecondsPath\"")
|
|
82
104
|
end
|
|
83
105
|
|
|
84
106
|
def success?(context)
|
|
85
107
|
runner.success?(context.state["RunnerContext"])
|
|
86
108
|
end
|
|
87
109
|
|
|
110
|
+
def timed_out?(context)
|
|
111
|
+
return false if timeout_seconds.nil? && timeout_seconds_path.nil?
|
|
112
|
+
|
|
113
|
+
timeout = timeout_seconds || timeout_seconds_path.value(context, context.input)
|
|
114
|
+
entered_time = Time.parse(context.state["EnteredTime"])
|
|
115
|
+
|
|
116
|
+
Time.now.utc > entered_time + timeout
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def task_timed_out!(context)
|
|
120
|
+
context.state["RunnerContext"]["Error"] = "States.Timeout"
|
|
121
|
+
context.state["RunnerContext"]["Cause"] = "Task timed out"
|
|
122
|
+
|
|
123
|
+
false
|
|
124
|
+
end
|
|
125
|
+
|
|
88
126
|
def parse_error(output)
|
|
89
127
|
return if output.nil?
|
|
90
128
|
return output if output.kind_of?(Hash)
|
data/lib/floe/workflow.rb
CHANGED
|
@@ -150,15 +150,7 @@ module Floe
|
|
|
150
150
|
|
|
151
151
|
# setup a workflow
|
|
152
152
|
def start_workflow
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
context.state["Name"] = start_at
|
|
156
|
-
context.state["Input"] = context.execution["Input"].dup
|
|
157
|
-
context.state["Guid"] = SecureRandom.uuid
|
|
158
|
-
|
|
159
|
-
context.execution["Id"] ||= SecureRandom.uuid
|
|
160
|
-
context.execution["StartTime"] = Time.now.utc.iso8601
|
|
161
|
-
|
|
153
|
+
context.prepare_start(start_at)
|
|
162
154
|
self
|
|
163
155
|
end
|
|
164
156
|
|
|
@@ -183,7 +175,7 @@ module Floe
|
|
|
183
175
|
|
|
184
176
|
# if rerunning due to an error (and we are using Retry)
|
|
185
177
|
if context.state_name == context.next_state && context.failed? && context.state.key?("Retrier")
|
|
186
|
-
next_state.merge!(context.state.slice("RetryCount", "Input", "Retrier"))
|
|
178
|
+
next_state.merge!(context.state.slice("RetryCount", "Input", "Retrier", "WaitUntil"))
|
|
187
179
|
else
|
|
188
180
|
next_state["Input"] = context.output
|
|
189
181
|
end
|
data/lib/floe.rb
CHANGED
|
@@ -54,17 +54,36 @@ module Floe
|
|
|
54
54
|
class InvalidExecutionInput < Error; end
|
|
55
55
|
|
|
56
56
|
class ExecutionError < Error
|
|
57
|
+
def self.from_output(output)
|
|
58
|
+
raise ArgumentError unless output.kind_of?(Hash) && output.key?("Error")
|
|
59
|
+
|
|
60
|
+
new(output["Cause"], output["Error"])
|
|
61
|
+
end
|
|
62
|
+
|
|
57
63
|
attr_reader :floe_error
|
|
58
64
|
|
|
59
65
|
def initialize(message, floe_error = "States.Runtime")
|
|
60
66
|
super(message)
|
|
61
67
|
@floe_error = floe_error
|
|
62
68
|
end
|
|
69
|
+
|
|
70
|
+
def to_output
|
|
71
|
+
{"Error" => floe_error}.tap do |output|
|
|
72
|
+
# If there is no "Cause" then ::Exception will use the exception class name
|
|
73
|
+
output["Cause"] = message if message != self.class.name.to_s
|
|
74
|
+
end
|
|
75
|
+
end
|
|
63
76
|
end
|
|
64
77
|
|
|
65
78
|
class PathError < ExecutionError
|
|
66
79
|
end
|
|
67
80
|
|
|
81
|
+
class TimeoutError < ExecutionError
|
|
82
|
+
def initialize(message = nil)
|
|
83
|
+
super(message, "States.Timeout")
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
68
87
|
def self.logger
|
|
69
88
|
@logger ||= NullLogger.new
|
|
70
89
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: floe
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ManageIQ Developers
|
|
@@ -225,10 +225,8 @@ executables:
|
|
|
225
225
|
extensions: []
|
|
226
226
|
extra_rdoc_files: []
|
|
227
227
|
files:
|
|
228
|
-
- ".codeclimate.yml"
|
|
229
228
|
- ".rspec"
|
|
230
229
|
- ".rubocop.yml"
|
|
231
|
-
- ".rubocop_cc.yml"
|
|
232
230
|
- ".rubocop_local.yml"
|
|
233
231
|
- ".yamllint"
|
|
234
232
|
- CHANGELOG.md
|
|
@@ -238,6 +236,7 @@ files:
|
|
|
238
236
|
- Rakefile
|
|
239
237
|
- examples/everything.asl
|
|
240
238
|
- examples/http.asl
|
|
239
|
+
- examples/log.asl
|
|
241
240
|
- examples/map.asl
|
|
242
241
|
- examples/parallel.asl
|
|
243
242
|
- examples/set-credential.asl
|
data/.codeclimate.yml
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
version: '2'
|
|
2
|
-
prepare:
|
|
3
|
-
fetch:
|
|
4
|
-
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_base.yml
|
|
5
|
-
path: ".rubocop_base.yml"
|
|
6
|
-
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_cc_base.yml
|
|
7
|
-
path: ".rubocop_cc_base.yml"
|
|
8
|
-
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/base.yml
|
|
9
|
-
path: styles/base.yml
|
|
10
|
-
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/cc_base.yml
|
|
11
|
-
path: styles/cc_base.yml
|
|
12
|
-
checks:
|
|
13
|
-
argument-count:
|
|
14
|
-
enabled: false
|
|
15
|
-
complex-logic:
|
|
16
|
-
enabled: false
|
|
17
|
-
file-lines:
|
|
18
|
-
enabled: false
|
|
19
|
-
method-complexity:
|
|
20
|
-
config:
|
|
21
|
-
threshold: 11
|
|
22
|
-
method-count:
|
|
23
|
-
enabled: false
|
|
24
|
-
method-lines:
|
|
25
|
-
enabled: false
|
|
26
|
-
nested-control-flow:
|
|
27
|
-
enabled: false
|
|
28
|
-
return-statements:
|
|
29
|
-
enabled: false
|
|
30
|
-
plugins:
|
|
31
|
-
rubocop:
|
|
32
|
-
enabled: true
|
|
33
|
-
config: ".rubocop_cc.yml"
|
|
34
|
-
channel: rubocop-1-56-3
|
|
35
|
-
exclude_patterns:
|
|
36
|
-
- spec/
|
data/.rubocop_cc.yml
DELETED