wrapbox 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c76da62eee815c3ab4d57a567a8a83810d9b7f20
4
- data.tar.gz: 4c3df8f6ce34d0ae48f476d32e57d85170ce0028
3
+ metadata.gz: edc9210efdc2d7248e0b6eab05f04c89f7223b90
4
+ data.tar.gz: afe62fcbfbf5f5383b12e476709fd7d79a36af27
5
5
  SHA512:
6
- metadata.gz: c2b799ee4e165c93dcf829659e513d610ad07f666377b8c3631c63209175bee00f7431b233dec3615cbd6dcba509895b4f4f7fa1e21b6b5174e7eb68d1673b22
7
- data.tar.gz: 600bd6d4359e2534bf0c047621d61b2a7df7d5bcbe9143eb84e465b081f6714744027c9cf2ff989615c468cb6893b664b21b3aa6fb61322f558e71cc1048e0f1
6
+ metadata.gz: 8f856b7dc58a1776c662f4bd43d1165c043c4ec8a2e5ad0a12eac1b4c60a1162d9ef57541c1d54373471f59879f6257cd8ae1105c1b26e142ffc790839694f75
7
+ data.tar.gz: 0cc10bf941d6b73d320581ae722383c888f5cac1fe700bfccfd5b5ab117abd3b1347abb5f67229d8048d1ff784768224122dd8c767f7188888489b1877a0e559
data/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  FROM ruby:alpine
2
2
 
3
- RUN apk add --no-cache git
3
+ RUN apk add --no-cache git gcc make g++ zlib-dev
4
4
  WORKDIR /app
5
5
  COPY . /app/
6
6
 
7
- RUN bundle install
7
+ RUN bundle install -j3
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "wrapbox/cli"
4
+
5
+ Wrapbox::Cli.start
@@ -0,0 +1,10 @@
1
+ require "thor/group"
2
+ require "wrapbox/runner/docker"
3
+ require "wrapbox/runner/ecs"
4
+
5
+ module Wrapbox
6
+ class Cli < Thor
7
+ register(Wrapbox::Runner::Ecs::Cli, "ecs", "ecs [COMMAND]", "Commands for ECS")
8
+ register(Wrapbox::Runner::Docker::Cli, "docker", "docker [COMMAND]", "Commands for Docker")
9
+ end
10
+ end
@@ -1,4 +1,5 @@
1
1
  require 'yaml'
2
+ require 'wrapbox/configuration'
2
3
 
3
4
  module Wrapbox
4
5
  class ConfigRepository
@@ -4,26 +4,32 @@ require "active_support/core_ext/string"
4
4
  module Wrapbox
5
5
  Configuration = Struct.new(
6
6
  :name,
7
+ :revision,
7
8
  :runner,
8
9
  :cluster,
9
10
  :region,
11
+ :retry,
12
+ :retry_interval,
13
+ :retry_interval_multiplier,
10
14
  :container_definition,
11
15
  :additional_container_definitions,
12
16
  :task_role_arn,
13
- :use_sudo,
14
- :rm
17
+ :keep_container
15
18
  ) do
16
19
  def self.load_config(config)
17
20
  new(
18
21
  config["name"],
22
+ config["revision"],
19
23
  config["runner"] ? config["runner"].to_sym : :docker,
20
24
  config["cluster"],
21
25
  config["region"],
26
+ config["retry"] || 0,
27
+ config["retry_interval"] || 1,
28
+ config["retry_interval_multiplier"] || 2,
22
29
  config["container_definition"].deep_symbolize_keys,
23
30
  config["additional_container_definitions"] || [],
24
31
  config["task_role_arn"],
25
- config["use_sudo"].nil? ? false : config["use_sudo"],
26
- config["rm"].nil? ? false : config["rm"]
32
+ config["keep_container"]
27
33
  )
28
34
  end
29
35
 
@@ -31,11 +37,11 @@ module Wrapbox
31
37
 
32
38
  def initialize(*args)
33
39
  super
34
- raise "#{runner} is unsupported runner" unless AVAILABLE_RUNNERS.include?(runner)
35
- require "wrapbox/runner/#{runner}"
36
40
  end
37
41
 
38
42
  def build_runner
43
+ raise "#{runner} is unsupported runner" unless AVAILABLE_RUNNERS.include?(runner.to_sym)
44
+ require "wrapbox/runner/#{runner}"
39
45
  Wrapbox::Runner.const_get(runner.to_s.camelcase).new(to_h)
40
46
  end
41
47
 
@@ -1,5 +1,7 @@
1
1
  require "open3"
2
2
  require "multi_json"
3
+ require "docker"
4
+ require "thor"
3
5
 
4
6
  module Wrapbox
5
7
  module Runner
@@ -9,86 +11,105 @@ module Wrapbox
9
11
  attr_reader \
10
12
  :name,
11
13
  :container_definition,
12
- :rm,
13
- :use_sudo
14
+ :keep_container
14
15
 
15
16
  def initialize(options)
16
17
  @name = options[:name]
17
18
  @container_definition = options[:container_definition]
18
- @rm = options[:rm]
19
- @use_sudo = options[:use_sudo]
19
+ @keep_container = options[:keep_container]
20
20
  end
21
21
 
22
22
  def run(class_name, method_name, args, container_definition_overrides: {}, environments: [])
23
23
  definition = container_definition
24
24
  .merge(container_definition_overrides)
25
25
 
26
- cmdopt = build_cmdopt(definition)
27
- cmdopt.concat(base_environments(class_name, method_name, args))
28
- cmdopt.concat(extract_environments(environments))
29
- cmdopt.concat([definition[:image], "bundle", "exec", "rake", "wrapbox:run"])
26
+ envs = base_environments(class_name, method_name, args)
27
+ envs.concat(extract_environments(environments))
30
28
 
31
- exec_docker(*cmdopt)
29
+ exec_docker(definition: definition, cmd: ["bundle", "exec", "rake", "wrapbox:run"], environments: envs)
32
30
  end
33
31
 
34
32
  def run_cmd(*cmd, container_definition_overrides: {}, environments: [])
35
33
  definition = container_definition
36
34
  .merge(container_definition_overrides)
37
35
 
38
- cmdopt = build_cmdopt(definition)
39
- cmdopt.concat(extract_environments(environments))
40
- cmdopt.concat([definition[:image], *cmd])
36
+ environments = extract_environments(environments)
41
37
 
42
- exec_docker(*cmdopt)
38
+ exec_docker(definition: definition, cmd: cmd, environments: environments)
43
39
  end
44
40
 
45
41
  private
46
42
 
47
- def build_cmdopt(definition)
48
- cmdopt = ["run"]
49
- cmdopt.concat(["--rm"]) if rm
50
- cmdopt.concat(["--cpu-shares", definition[:cpu].to_s]) if definition[:cpu]
51
- cmdopt.concat(["--memory", "#{definition[:memory]}m"]) if definition[:memory]
52
- cmdopt.concat(["--memory-reservation", "#{definition[:memory_reservation]}m"]) if definition[:memory_reservation]
53
- cmdopt
54
- end
55
-
56
43
  def base_environments(class_name, method_name, args)
57
- ["-e", "#{CLASS_NAME_ENV}=#{class_name}", "-e", "#{METHOD_NAME_ENV}=#{method_name}", "-e", "#{METHOD_ARGS_ENV}=#{MultiJson.dump(args)}"]
44
+ ["#{CLASS_NAME_ENV}=#{class_name}", "#{METHOD_NAME_ENV}=#{method_name}", "#{METHOD_ARGS_ENV}=#{MultiJson.dump(args)}"]
58
45
  end
59
46
 
60
47
  def extract_environments(environments)
61
- environments.flat_map do |e|
62
- ["-e", "#{e[:name]}=#{e[:value]}"]
48
+ environments.map do |e|
49
+ "#{e[:name]}=#{e[:value]}"
50
+ end
51
+ end
52
+
53
+ def exec_docker(definition:, cmd:, environments: [])
54
+ ::Docker::Image.create("fromImage" => definition[:image])
55
+ options = {
56
+ "Image" => definition[:image],
57
+ "Cmd" => cmd,
58
+ "Env" => environments,
59
+ }
60
+ options["HostConfig"] = {}
61
+ options["HostConfig"]["Cpu"] = definition[:cpu] if definition[:cpu]
62
+ options["HostConfig"]["Memory"] = definition[:memory] * 1024 * 1024 if definition[:memory]
63
+ options["HostConfig"]["MemoryReservation"] = definition[:memory_reservation] * 1024 * 1024 if definition[:memory_reservation]
64
+ options["HostConfig"]["Links"] = definition[:links]
65
+ options["Entrypoint"] = definition[:entry_point] if definition[:entry_point]
66
+ options["WorkingDir"] = definition[:working_directory] if definition[:working_directory]
67
+
68
+ container = ::Docker::Container.create(options)
69
+
70
+ container.start!
71
+ output_container_logs(container)
72
+ resp = container.wait
73
+ output_container_logs(container)
74
+
75
+ unless resp["StatusCode"].zero?
76
+ raise ExecutionError, "exit_code=#{resp["StatusCode"]}"
63
77
  end
78
+ ensure
79
+ container.remove(force: true) if container && !keep_container
64
80
  end
65
81
 
66
- def exec_docker(*args)
67
- cmd = use_sudo ? "sudo docker" : "docker"
68
-
69
- result = Open3.popen3(cmd, *args) do |stdin, stdout, stderr, wait_thr|
70
- stdin.close_write
71
- begin
72
- loop do
73
- rs, _ = IO.select([stdout, stderr])
74
- rs.each do |io|
75
- io.each do |line|
76
- next if line.nil? || line.empty?
77
- if io == stdout
78
- $stdout.puts(line)
79
- else
80
- $stderr.puts(line)
81
- end
82
- end
83
- end
84
- break if stdout.eof? && stderr.eof?
85
- end
86
- rescue EOFError
82
+ def output_container_logs(container)
83
+ container.streaming_logs(stdout: true, stderr: true) do |stream, chunk|
84
+ if stream == "stdout"
85
+ $stdout.puts(chunk)
86
+ else
87
+ $stderr.puts(chunk)
87
88
  end
88
- wait_thr.value
89
89
  end
90
+ end
90
91
 
91
- raise ExecutionError, "exit_code=#{result.exitstatus}" unless result.success?
92
+ class Cli < Thor
93
+ namespace :docker
94
+
95
+ desc "run_cmd [shell command]", "Run shell on docker"
96
+ method_option :config, aliases: "-f", required: true, banner: "YAML_FILE", desc: "yaml file path"
97
+ method_option :config_name, aliases: "-n", required: true, default: "default"
98
+ method_option :environments, aliases: "-e"
99
+ def run_cmd(*args)
100
+ if args.size == 1
101
+ args = args[0].split(" ")
102
+ end
103
+
104
+ repo = Wrapbox::ConfigRepository.new.tap { |r| r.load_yaml(options[:config]) }
105
+ config = repo.get(options[:config_name])
106
+ config.runner = :docker
107
+ runner = config.build_runner
108
+ environments = options[:environments].to_s.split(/,\s*/).map { |kv| kv.split("=") }.map do |k, v|
109
+ {name: k, value: v}
110
+ end
111
+ runner.run_cmd(*args, environments: environments)
112
+ end
92
113
  end
93
114
  end
94
115
  end
@@ -1,13 +1,22 @@
1
1
  require "aws-sdk"
2
2
  require "multi_json"
3
+ require "thor"
4
+ require "yaml"
5
+ require "active_support/core_ext/hash"
6
+ require "logger"
7
+
8
+ require "wrapbox/config_repository"
9
+ require "wrapbox/version"
3
10
 
4
11
  module Wrapbox
5
12
  module Runner
6
13
  class Ecs
7
14
  class ExecutionError < StandardError; end
15
+ class LaunchFailure < StandardError; end
8
16
 
9
17
  attr_reader \
10
18
  :name,
19
+ :revision,
11
20
  :cluster,
12
21
  :region,
13
22
  :container_definition,
@@ -16,28 +25,33 @@ module Wrapbox
16
25
 
17
26
  def initialize(options)
18
27
  @name = options[:name]
28
+ @revision = options[:revision]
19
29
  @cluster = options[:cluster]
20
30
  @region = options[:region]
21
31
  @container_definition = options[:container_definition]
22
32
  @additional_container_definitions = options[:additional_container_definitions]
23
33
  @task_role_arn = options[:task_role_arn]
34
+ @logger = Logger.new($stdout)
24
35
  end
25
36
 
26
- def run(class_name, method_name, args, container_definition_overrides: {}, environments: [], task_role_arn: nil, cluster: nil, timeout: 3600 * 24, launch_timeout: 60 * 10, launch_retry: 10)
37
+ def run(class_name, method_name, args, container_definition_overrides: {}, environments: [], task_role_arn: nil, cluster: nil, timeout: 3600 * 24, launch_timeout: 60 * 10, launch_retry: 10, retry_interval: 1, retry_interval_multiplier: 2, max_retry_interval: 120)
27
38
  task_definition = register_task_definition(container_definition_overrides)
28
39
  run_task(
29
40
  task_definition.task_definition_arn, class_name, method_name, args,
30
41
  command: ["bundle", "exec", "rake", "wrapbox:run"],
31
42
  environments: environments,
32
- task_role_arn: task_role_arn,
43
+ task_role_arn: task_role_arn || @task_role_arn,
33
44
  cluster: cluster,
34
45
  timeout: timeout,
35
46
  launch_timeout: launch_timeout,
36
47
  launch_retry: launch_retry,
48
+ retry_interval: retry_interval,
49
+ retry_interval_multiplier: retry_interval_multiplier,
50
+ max_retry_interval: max_retry_interval,
37
51
  )
38
52
  end
39
53
 
40
- def run_cmd(*cmd, container_definition_overrides: {}, environments: [], task_role_arn: nil, cluster: nil, timeout: 3600 * 24, launch_timeout: 60 * 10, launch_retry: 10)
54
+ def run_cmd(*cmd, container_definition_overrides: {}, environments: [], task_role_arn: nil, cluster: nil, timeout: 3600 * 24, launch_timeout: 60 * 10, launch_retry: 10, retry_interval: 1, retry_interval_multiplier: 2, max_retry_interval: 120)
41
55
  task_definition = register_task_definition(container_definition_overrides)
42
56
 
43
57
  run_task(
@@ -49,52 +63,64 @@ module Wrapbox
49
63
  timeout: timeout,
50
64
  launch_timeout: launch_timeout,
51
65
  launch_retry: launch_retry,
66
+ retry_interval: retry_interval,
67
+ retry_interval_multiplier: retry_interval_multiplier,
68
+ max_retry_interval: max_retry_interval,
52
69
  )
53
70
  end
54
71
 
55
- def run_task(task_definition_arn, class_name, method_name, args, command:, environments: [], task_role_arn: nil, cluster: nil, timeout: 3600 * 24, launch_timeout: 60 * 10, launch_retry: 10)
72
+ def run_task(task_definition_arn, class_name, method_name, args, command:, environments: [], task_role_arn: nil, cluster: nil, timeout: 3600 * 24, launch_timeout: 60 * 10, launch_retry: 10, retry_interval: 1, retry_interval_multiplier: 2, max_retry_interval: 120)
56
73
  cl = cluster || self.cluster
57
74
  args = Array(args)
58
75
 
59
- task = client
60
- .run_task(build_run_task_options(class_name, method_name, args, command, environments, cluster, task_definition_arn, task_role_arn))
61
- .tasks[0]
62
-
63
76
  launch_try_count = 0
77
+ current_retry_interval = retry_interval
78
+ task = nil
79
+ exit_code = nil
64
80
  begin
65
- launched_at = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
81
+ task = client
82
+ .run_task(build_run_task_options(class_name, method_name, args, command, environments, cluster, task_definition_arn, task_role_arn))
83
+ .tasks[0]
84
+ raise LaunchFailure unless task
85
+ @logger.debug("Create Task: #{task.task_arn}")
66
86
  client.wait_until(:tasks_running, cluster: cl, tasks: [task.task_arn]) do |w|
67
87
  if launch_timeout
88
+ w.delay = 5
89
+ w.max_attempts = launch_timeout / w.delay
90
+ else
68
91
  w.max_attempts = nil
69
- w.before_wait do
70
- throw :failure if Process.clock_gettime(Process::CLOCK_MONOTONIC, :second) - launched_at > launch_timeout
71
- end
72
92
  end
73
93
  end
74
- rescue Aws::Waiters::Errors::TooManyAttemptsError
75
- if launch_try_count >= launch_retry
76
- client.stop_task(
77
- cluster: cl,
78
- task: task.task_arn,
79
- reason: "launch timeout"
80
- )
81
- raise
82
- else
83
- put_waiting_task_count_metric(cl)
84
- launch_try_count += 1
85
- retry
94
+ rescue Aws::Waiters::Errors::WaiterFailed, LaunchFailure
95
+ exit_code = task && fetch_exit_code(cl, task.task_arn)
96
+ unless exit_code
97
+ if launch_try_count >= launch_retry
98
+ client.stop_task(
99
+ cluster: cl,
100
+ task: task.task_arn,
101
+ reason: "launch timeout"
102
+ ) if task
103
+ raise
104
+ else
105
+ put_waiting_task_count_metric(cl)
106
+ launch_try_count += 1
107
+ @logger.debug("Retry Create Task after #{current_retry_interval} sec")
108
+ sleep current_retry_interval
109
+ current_retry_interval = [current_retry_interval * retry_interval_multiplier, max_retry_interval].min
110
+ retry
111
+ end
86
112
  end
87
- rescue Aws::Waiters::Errors::WaiterFailed
88
113
  end
89
114
 
115
+ @logger.debug("Launch Task: #{task.task_arn}")
116
+
90
117
  begin
91
- started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
92
118
  client.wait_until(:tasks_stopped, cluster: cl, tasks: [task.task_arn]) do |w|
93
119
  if timeout
120
+ w.delay = 5
121
+ w.max_attempts = timeout / w.delay
122
+ else
94
123
  w.max_attempts = nil
95
- w.before_wait do
96
- throw :failure if Process.clock_gettime(Process::CLOCK_MONOTONIC, :second) - started_at > timeout
97
- end
98
124
  end
99
125
  end
100
126
  rescue Aws::Waiters::Errors::TooManyAttemptsError
@@ -103,12 +129,14 @@ module Wrapbox
103
129
  task: task.task_arn,
104
130
  reason: "process timeout",
105
131
  })
132
+ raise ExecutionError, "process timeout"
106
133
  end
107
134
 
108
- task = client.describe_tasks(cluster: cl, tasks: [task.task_arn]).tasks[0]
109
- container = task.containers.find { |c| c.name = task_definition_name }
110
- unless container.exit_code == 0
111
- raise ExecutionError, "Container #{task_definition_name} is failed. exit_code=#{container.exit_code}"
135
+ @logger.debug("Stop Task: #{task.task_arn}")
136
+
137
+ exit_code ||= fetch_exit_code(cl, task.task_arn)
138
+ unless exit_code == 0
139
+ raise ExecutionError, "Container #{task_definition_name} is failed. exit_code=#{exit_code}"
112
140
  end
113
141
  end
114
142
 
@@ -118,11 +146,25 @@ module Wrapbox
118
146
  "wrapbox_#{name}"
119
147
  end
120
148
 
149
+ def fetch_exit_code(cluster, task_arn)
150
+ task = client.describe_tasks(cluster: cluster, tasks: [task_arn]).tasks[0]
151
+ container = task.containers.find { |c| c.name = task_definition_name }
152
+ container.exit_code
153
+ end
154
+
121
155
  def register_task_definition(container_definition_overrides)
122
156
  definition = container_definition
123
157
  .merge(container_definition_overrides)
124
158
  .merge(name: task_definition_name)
125
159
  container_definitions = [definition, *additional_container_definitions]
160
+
161
+ if revision
162
+ begin
163
+ return client.describe_task_definition(task_definition: "#{task_definition_name}:#{revision}").task_definition
164
+ rescue
165
+ end
166
+ end
167
+
126
168
  client.register_task_definition({
127
169
  family: task_definition_name,
128
170
  container_definitions: container_definitions,
@@ -142,7 +184,7 @@ module Wrapbox
142
184
 
143
185
  options = {}
144
186
  options[:region] = region if region
145
- @cloud_watch_client = Aws::CloudWatch::Client.new
187
+ @cloud_watch_client = Aws::CloudWatch::Client.new(options)
146
188
  end
147
189
 
148
190
  def put_waiting_task_count_metric(cluster)
@@ -197,6 +239,42 @@ module Wrapbox
197
239
  started_by: "wrapbox-#{Wrapbox::VERSION}",
198
240
  }
199
241
  end
242
+
243
+ class Cli < Thor
244
+ namespace :ecs
245
+
246
+ desc "run_cmd [shell command]", "Run shell on ECS"
247
+ method_option :config, aliases: "-f", required: true, banner: "YAML_FILE", desc: "yaml file path"
248
+ method_option :config_name, aliases: "-n", required: true, default: "default"
249
+ method_option :cluster, aliases: "-c"
250
+ method_option :environments, aliases: "-e"
251
+ method_option :task_role_arn
252
+ method_option :timeout, type: :numeric
253
+ method_option :launch_timeout, type: :numeric
254
+ method_option :launch_retry, type: :numeric
255
+ method_option :max_retry_interval, type: :numeric
256
+ def run_cmd(*args)
257
+ if args.size == 1
258
+ args = args[0].split(" ")
259
+ end
260
+
261
+ repo = Wrapbox::ConfigRepository.new.tap { |r| r.load_yaml(options[:config]) }
262
+ config = repo.get(options[:config_name])
263
+ config.runner = :ecs
264
+ runner = config.build_runner
265
+ environments = options[:environments].to_s.split(/,\s*/).map { |kv| kv.split("=") }.map do |k, v|
266
+ {name: k, value: v}
267
+ end
268
+ run_options = {
269
+ task_role_arn: options[:task_role_arn],
270
+ timeout: options[:timeout],
271
+ launch_timeout: options[:launch_timeout],
272
+ launch_retry: options[:launch_retry],
273
+ max_retry_interval: options[:max_retry_interval]
274
+ }.reject { |_, v| v.nil? }
275
+ runner.run_cmd(*args, environments: environments, **run_options)
276
+ end
277
+ end
200
278
  end
201
279
  end
202
280
  end
@@ -1,3 +1,3 @@
1
1
  module Wrapbox
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -22,7 +22,9 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_runtime_dependency "aws-sdk", "~> 2.4"
24
24
  spec.add_runtime_dependency "activesupport", ">= 4"
25
+ spec.add_runtime_dependency "docker-api"
25
26
  spec.add_runtime_dependency "multi_json"
27
+ spec.add_runtime_dependency "thor"
26
28
 
27
29
  spec.add_development_dependency "bundler", "~> 1.13"
28
30
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wrapbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - joker1007
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-31 00:00:00.000000000 Z
11
+ date: 2017-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: docker-api
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: multi_json
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: thor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: bundler
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -139,7 +167,8 @@ dependencies:
139
167
  description: Ruby method runner on AWS ECS
140
168
  email:
141
169
  - kakyoin.hierophant@gmail.com
142
- executables: []
170
+ executables:
171
+ - wrapbox
143
172
  extensions: []
144
173
  extra_rdoc_files: []
145
174
  files:
@@ -153,7 +182,9 @@ files:
153
182
  - Rakefile
154
183
  - bin/console
155
184
  - bin/setup
185
+ - exe/wrapbox
156
186
  - lib/wrapbox.rb
187
+ - lib/wrapbox/cli.rb
157
188
  - lib/wrapbox/config_repository.rb
158
189
  - lib/wrapbox/configuration.rb
159
190
  - lib/wrapbox/job.rb
@@ -181,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
212
  version: '0'
182
213
  requirements: []
183
214
  rubyforge_project:
184
- rubygems_version: 2.6.4
215
+ rubygems_version: 2.6.8
185
216
  signing_key:
186
217
  specification_version: 4
187
218
  summary: Ruby method runner on AWS ECS