full360-sequencer 0.0.2
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/bin/sequencer +36 -0
- data/lib/full360-sequencer.rb +146 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61e19b3c9ee3020cf5722e1c6caed5168fa5ddd2702105fb4a206bdfa58f9cbe
|
4
|
+
data.tar.gz: e2b2f543e1e495c65d7c9556a5bba6c122ca3a802b46acb993e6be61a1b0bc87
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 20ea331819a466dd1e91dca8297222ee02f7a9d3393ab77f95a58deaf3a180b4c9c84e59443fafa42c060ce7fc40e16954d30759b813b1ed8047c4791e72da04
|
7
|
+
data.tar.gz: efa98dec9320a33e126ccb3e0c7d6c8866218b5d5ef71589e727d07e197eba38dadfaaff3b1a6467bc3ccc7262e29217f16f03b9c7fc4973a5e159296578c591
|
data/bin/sequencer
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'full360-sequencer'
|
4
|
+
|
5
|
+
config_file = ARGV[0]
|
6
|
+
|
7
|
+
# configure global logger
|
8
|
+
module Sequencer
|
9
|
+
Log = Logger.new(STDOUT)
|
10
|
+
end
|
11
|
+
|
12
|
+
def logger
|
13
|
+
Sequencer::Log
|
14
|
+
end
|
15
|
+
|
16
|
+
def sequencer_version
|
17
|
+
Gem.loaded_specs['full360-sequencer'].version
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
logger.info("sequencer version #{sequencer_version}")
|
22
|
+
logger.level = ENV['SEQUENCER_LOG_DEBUG'] ? Logger::DEBUG : Logger::INFO
|
23
|
+
|
24
|
+
if config_file == nil
|
25
|
+
logger.error('YAML file not provided... exiting with error code 1')
|
26
|
+
exit 1
|
27
|
+
else
|
28
|
+
r = Full360::Sequencer::Runner.new(logger)
|
29
|
+
r.config_from_file(config_file)
|
30
|
+
r.sleep_between_checks = ENV['SEQUENCER_SLEEP_BETWEEN_CHECKS'].to_i if ENV['SEQUENCER_SLEEP_BETWEEN_CHECKS']
|
31
|
+
r.run
|
32
|
+
end
|
33
|
+
rescue => e
|
34
|
+
logger.error(e.message)
|
35
|
+
e.backtrace.each { |r| logger.error(r) }
|
36
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'aws-sdk'
|
3
|
+
require 'yaml'
|
4
|
+
require 'logger'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
module Full360
|
8
|
+
module Sequencer
|
9
|
+
class Runner
|
10
|
+
attr_accessor :sleep_between_checks
|
11
|
+
attr_accessor :config
|
12
|
+
|
13
|
+
def initialize(logger = nil)
|
14
|
+
@logger = logger ? logger : Logger.new(STDOUT)
|
15
|
+
|
16
|
+
# default 5 seconds between completed? checks
|
17
|
+
@sleep_between_checks = 5
|
18
|
+
end
|
19
|
+
|
20
|
+
def config_from_file(yaml_path)
|
21
|
+
@config = parse_config_file(yaml_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_task_class(task_type_string)
|
25
|
+
case task_type_string
|
26
|
+
when 'ecs_task' then Full360::Sequencer::RunECSTask
|
27
|
+
else nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def run
|
32
|
+
@config.each do |params|
|
33
|
+
this_task_name = task_name(params)
|
34
|
+
this_task = run_task_class(params[this_task_name]['type']).new(
|
35
|
+
this_task_name,
|
36
|
+
params[this_task_name]
|
37
|
+
)
|
38
|
+
this_task.run_task
|
39
|
+
until this_task.completed?
|
40
|
+
sleep @sleep_between_checks
|
41
|
+
end
|
42
|
+
raise "task failed error" unless this_task.success
|
43
|
+
end
|
44
|
+
rescue => e
|
45
|
+
@logger.error(e.message)
|
46
|
+
e.backtrace.each { |r| @logger.error(r) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def task_name(params)
|
50
|
+
params.keys.first
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_config_file(yaml_path)
|
54
|
+
YAML.load_file(yaml_path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def config_valid?(config)
|
58
|
+
return false unless config.is_a? Array
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class RunTaskBase
|
64
|
+
attr_reader :success
|
65
|
+
attr_reader :exit_code
|
66
|
+
|
67
|
+
def run_task; end
|
68
|
+
def completed?; end
|
69
|
+
def kill_task; end #will be used for timeout
|
70
|
+
end
|
71
|
+
|
72
|
+
class RunECSTask < RunTaskBase
|
73
|
+
def initialize(task_name, params, logger = nil)
|
74
|
+
@logger = logger ? logger : Logger.new(STDOUT)
|
75
|
+
@task_name = task_name
|
76
|
+
@params = params['parameters']
|
77
|
+
@params = keys_to_symbol(@params)
|
78
|
+
@cluster = @params[:cluster]
|
79
|
+
end
|
80
|
+
|
81
|
+
def keys_to_symbol(params)
|
82
|
+
# replaces string keys with symbol keys
|
83
|
+
# required by AWS SDK
|
84
|
+
if params.is_a?(Hash)
|
85
|
+
params.inject({}){ |memo,(k,v)| memo[k.to_sym] = v; memo }
|
86
|
+
else
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def run_task
|
92
|
+
@logger.info("starting ECS task #{@task_name}")
|
93
|
+
@logger.debug("creating AWS client for ECS task #{@task_name}...")
|
94
|
+
@ecs_client = ::Aws::ECS::Client.new
|
95
|
+
@logger.debug("running ECS task #{@task_name}...")
|
96
|
+
@start_time = Time.new
|
97
|
+
resp = @ecs_client.run_task(@params)
|
98
|
+
@task_arn = resp.tasks[0].task_arn
|
99
|
+
@logger.info("#{@task_name} task created #{@task_arn} on cluster #{@cluster}")
|
100
|
+
end
|
101
|
+
|
102
|
+
def ecs_describe_tasks
|
103
|
+
@ecs_client.describe_tasks(
|
104
|
+
{
|
105
|
+
cluster: @cluster,
|
106
|
+
tasks: [@task_arn] # required
|
107
|
+
}
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
def completed?
|
112
|
+
resp = ecs_describe_tasks
|
113
|
+
status = last_task_status(resp)
|
114
|
+
@logger.info("#{@task_name} : #{@task_arn} current status: #{status}")
|
115
|
+
if status == 'STOPPED'
|
116
|
+
@logger.info("#{@task_name} completed in #{Time.new - @start_time} seconds")
|
117
|
+
# parse exit_code(s) and return completion
|
118
|
+
@success = determine_success(resp)
|
119
|
+
return true
|
120
|
+
end
|
121
|
+
false
|
122
|
+
rescue => e
|
123
|
+
@logger.error(e.message)
|
124
|
+
e.backtrace.each { |r| @logger.error(r) }
|
125
|
+
end
|
126
|
+
|
127
|
+
# parses last status from aws API response
|
128
|
+
def last_task_status(resp)
|
129
|
+
resp.tasks[0].last_status
|
130
|
+
end
|
131
|
+
|
132
|
+
# success is determined by all containers having zero exit code
|
133
|
+
def determine_success(resp)
|
134
|
+
success = true
|
135
|
+
resp.tasks[0].containers.each do |c|
|
136
|
+
@logger.info("#{@task_name} : container #{c.name} #{c.container_arn} completed with exit_code #{c.exit_code}")
|
137
|
+
if c.exit_code != 0
|
138
|
+
# we had a problem!
|
139
|
+
success = false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
success
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: full360-sequencer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- pankaj batra
|
8
|
+
- jeremy winters
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2017-06-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
name: logger
|
21
|
+
prerelease: false
|
22
|
+
type: :runtime
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.2'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.9'
|
34
|
+
name: aws-sdk
|
35
|
+
prerelease: false
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.9'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.9'
|
48
|
+
name: minitest
|
49
|
+
prerelease: false
|
50
|
+
type: :development
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '5.9'
|
56
|
+
description: automation for simple batch jobs run in AWS
|
57
|
+
email: pankaj.batra@full360.com
|
58
|
+
executables:
|
59
|
+
- sequencer
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- bin/sequencer
|
64
|
+
- lib/full360-sequencer.rb
|
65
|
+
homepage: https://www.full360.com
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '2.0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.6.11
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: full360 sequencer utility
|
89
|
+
test_files: []
|