app-rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 23df7f2417cf94b6957cde15260ae950348d8861
4
+ data.tar.gz: 10198299029a90bada242c624e4bfc59bf3c3e1b
5
+ SHA512:
6
+ metadata.gz: 88b81b190edd57ee17b485e967303421e777f13fa39b22d4d27eed241e86d344ad122abe6db9d1371c8b0f5647ffa87f03550a21837b6ffb3c964bd77f1ba96e
7
+ data.tar.gz: 780f0b901f9ed60f2194855617ec896cd986d50a9b7eb2577b93e598b538f99846365c5bb51be38f7267d01b6a6a1475a9b3425344a250ede0acb39f49837106
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.2
5
+ before_install: gem install bundler -v 1.14.3
6
+ notifications:
7
+ email:
8
+ recipients:
9
+ - vakhov@gmail.com
10
+ on_success: never
11
+ on_failure: always
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## App-rb 0.1.0 (March 25, 2017) ##
2
+
3
+ * First public version.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in app-rb.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Alexey Vakhov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # app-rb
2
+
3
+ Powerfull docker apps deployer.
4
+
5
+ ## Installation
6
+
7
+ Install last gem version as:
8
+
9
+ $ gem install app-rb
10
+
11
+ ## Usage
12
+
13
+ Fire `app-rb` to print help.
14
+
15
+ ## Contributing
16
+
17
+ Bug reports and pull requests are welcome on GitHub at https://github.com/uchiru/app-rb.
18
+
19
+ ## License
20
+
21
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
22
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/app-rb.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'app-rb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "app-rb"
8
+ spec.version = AppRb::VERSION
9
+ spec.authors = ["Alexey Vakhov"]
10
+ spec.email = ["vakhov@gmail.com"]
11
+
12
+ spec.summary = %q{Easy deploy docker apps}
13
+ spec.description = %q{Deploy docker apps. Nothing else}
14
+ spec.homepage = "https://github.com/uchiru/app-rb"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.14"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ end
data/bin/release ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ VERSION_PATH = File.expand_path('../../lib/app-rb/version.rb', __FILE__)
4
+ CHANGELOG_PATH = File.expand_path('../../CHANGELOG.md', __FILE__)
5
+
6
+ current_version = File.read(VERSION_PATH).split("\n").find { |l| l.index("VERSION") }.split('"')[1]
7
+ major, minor, patch = current_version.split(".", 3).map(&:to_i)
8
+ dev = !!current_version.index("-dev")
9
+
10
+ if ARGV[0] == "patch" && !dev
11
+ version = "#{major}.#{minor}.#{patch + 1}"
12
+ next_version = "#{major}.#{minor}.#{patch + 1}"
13
+
14
+ elsif ARGV[0] == "minor" && dev && patch == 0
15
+ version = "#{major}.#{minor}.0"
16
+ next_version = "#{major}.#{minor + 1}.0-dev"
17
+
18
+ elsif ARGV[0] == "major" && dev && patch == 0
19
+ version = "#{major + 1}.0.0"
20
+ next_version = "#{major + 1}.1.0-dev"
21
+
22
+ else
23
+ puts "Current version: #{current_version}"
24
+ unless dev
25
+ puts "./bin/release patch # => #{major}.#{minor}.#{patch + 1}"
26
+ end
27
+ if dev
28
+ puts "./bin/release minor # => #{major}.#{minor}.0"
29
+ puts "./bin/release major # => #{major + 1}.0.0"
30
+ end
31
+ exit
32
+ end
33
+
34
+ def exec(cmd)
35
+ puts "[exec] #{cmd}"
36
+ system cmd
37
+ end
38
+
39
+ puts "releasing version: #{version}"
40
+ exec %(git add .)
41
+ exec %(git commit -am"uncommitted changes before release #{version}")
42
+ exec %(git pull --rebase)
43
+ File.write(VERSION_PATH, File.read(VERSION_PATH).sub(/VERSION = ".*?"/, %(VERSION = "#{version}")))
44
+ File.write(CHANGELOG_PATH, "## App-rb #{version} (#{Time.now.strftime("%B %-d, %Y")}) ##\n\n" + File.read(CHANGELOG_PATH))
45
+ exec %(git commit -am"Release #{version}")
46
+ exec %(git tag v#{version})
47
+ exec %(git push)
48
+ exec %(git push --tags)
49
+ exec %(gem build app-rb.gemspec)
50
+ exec %(gem push app-rb-#{version}.gem)
51
+ exec %(rm -f app-rb-#{version}.gem)
52
+ File.write(VERSION_PATH, File.read(VERSION_PATH).sub(/VERSION = ".*?"/, %(VERSION = "#{next_version}")))
53
+ exec %(git commit -am"Start version #{next_version}")
54
+ exec %(git push)
55
+
56
+ puts "Done."
data/exe/app-rb ADDED
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env ruby
2
+ require 'json'
3
+ require 'yaml'
4
+ require 'pp'
5
+ require 'open3'
6
+ Thread.abort_on_exception = true
7
+
8
+ def yellow(txt); "\e[0;33m#{txt}\e[0m"; end
9
+ def red(txt); "\e[0;31m#{txt}\e[0m"; end
10
+ def green(txt); "\e[0;32m#{txt}\e[0m"; end
11
+ def blue(txt); "\e[0;34m#{txt}\e[0m"; end
12
+
13
+ def do_it(cmd)
14
+ puts "[exec] #{cmd}"
15
+ system(cmd)
16
+ unless $?.success?
17
+ puts red("FATAL :(")
18
+ exit
19
+ end
20
+ end
21
+
22
+ def just_cmd(cmd, skip_exit_status = false)
23
+ puts "[exec] #{cmd}"
24
+ output = `#{cmd}`
25
+ if $?.success? || skip_exit_status
26
+ output.strip
27
+ else
28
+ puts red(output)
29
+ puts red("FATAL :(")
30
+ exit
31
+ end
32
+ end
33
+
34
+ if ARGV.count < 2
35
+ puts "Just deploy your apps with docker and consul. Nothing else."
36
+ puts ""
37
+ puts " #{$0} <yml> <command>"
38
+ puts ""
39
+ puts " deploy [hash] - deploy new version of app"
40
+ puts " status - status of app"
41
+ puts " stop - stop app"
42
+ exit
43
+ end
44
+
45
+ CONFIG = YAML.load(File.read(ARGV[0]))
46
+ COMMAND = ARGV[1]
47
+
48
+ MIN_PORT = 10_000
49
+ MAX_PORT = 50_000
50
+ Node = Struct.new(:name, :ip, :roles)
51
+ NODES = JSON.load(just_cmd("curl -s #{CONFIG["consul"]}/v1/catalog/nodes")).sort_by { |n|
52
+ n["Node"]
53
+ }.map { |n|
54
+ Node.new(n["Node"], n["Address"], (n["Meta"] || {})["roles"].to_s.split(",").reject{ |s| s.to_s.empty? })
55
+ }
56
+
57
+ def nodes(constraint)
58
+ constraint ||= {}
59
+ out = NODES
60
+ if constraint["role"]
61
+ out = out.select { |n| n.roles.index(constraint["role"]) }
62
+ end
63
+ if constraint["name"]
64
+ out = out.select { |n| n.name == constraint["name"] }
65
+ end
66
+ out
67
+ end
68
+
69
+ def node(constraint)
70
+ nodes(constraint).sample
71
+ end
72
+
73
+
74
+ def deploy(target = nil)
75
+ build_node = node(CONFIG["image"]["constraint"])
76
+ puts "build_node=#{build_node.to_h.inspect}"
77
+
78
+ puts blue("+++ CLONE or UPDATE repository")
79
+ do_it "ssh #{CONFIG["user"]}@#{build_node.ip} bash <<EOF
80
+ set -e
81
+ tmpfile=\\$(mktemp /tmp/git-ssh-#{CONFIG["app"]}.XXXXXX)
82
+ echo '#!/bin/sh' > \\$tmpfile
83
+ echo 'exec /usr/bin/ssh -o StrictHostKeyChecking=no -i #{CONFIG["image"]["key"]} \"\\$@\"' >> \\$tmpfile
84
+ chmod +x \\$tmpfile
85
+ export GIT_SSH=\\$tmpfile
86
+ if [ -d #{CONFIG["app"]}-cache ]; then
87
+ echo update cache...
88
+ cd #{CONFIG["app"]}-cache
89
+ git checkout . && git clean -dfx && git checkout master && git pull
90
+ git branch | grep -v master | xargs -r git branch -D
91
+ else
92
+ echo clone...
93
+ git clone git@github.com:#{CONFIG["image"]["repo"]} #{CONFIG["app"]}-cache && cd #{CONFIG["app"]}-cache
94
+ fi
95
+ git checkout #{target || CONFIG["image"]["target"]}
96
+ rm \\$tmpfile\nEOF"
97
+
98
+ puts blue("+++ calculate HASH and VERSION")
99
+ hash = ARGV[2] || `ssh #{CONFIG["user"]}@#{build_node.ip} 'cd #{CONFIG["app"]}-cache && git rev-parse HEAD'`.strip
100
+ puts "hash: #{hash}"
101
+
102
+ o = JSON.load(`curl -s https://#{CONFIG["registry"]}/v2/#{CONFIG["app"]}/tags/list`)
103
+ tags = o.is_a?(Hash) && o["errors"] ? [] : o["tags"]
104
+ puts "tags: #{JSON.dump(tags)}"
105
+
106
+ unless tags.index(hash)
107
+ puts blue("+++ BUILD image")
108
+ do_it "ssh #{CONFIG["user"]}@#{build_node.ip} bash <<EOF
109
+ set -e
110
+ cd #{CONFIG["app"]}-cache
111
+ #{(CONFIG["image"]["pre_build"] || []).join("\n")}
112
+ docker build -t #{CONFIG["registry"]}/#{CONFIG["app"]}:#{hash} .
113
+ docker push #{CONFIG["registry"]}/#{CONFIG["app"]}:#{hash}
114
+ echo Done.\nEOF"
115
+ end
116
+ vv = Time.now.to_i
117
+ new_service = "#{CONFIG["app"]}-#{vv}"
118
+
119
+ (CONFIG["deploy"]["pre"] || []).each_with_index do |section, index|
120
+ puts blue("+++ PRE: #{section.inspect}")
121
+ n = node(section["constraint"] || CONFIG["deploy"]["constraint"])
122
+ puts "node=#{n.inspect}"
123
+ do_it "ssh #{CONFIG["user"]}@#{n.ip} docker run " +
124
+ "--label app=#{CONFIG["app"]} " +
125
+ "--label service=#{new_service} " +
126
+ "--name #{CONFIG["app"]}-pre-#{vv}-#{index} " +
127
+ "#{(CONFIG["env"] || {}).map { |k, v| "-e #{k}='#{v}'" }.join(" ")} " +
128
+ "#{CONFIG["registry"]}/#{CONFIG["app"]}:#{hash} #{section["cmd"]}"
129
+ do_it "ssh #{CONFIG["user"]}@#{n.ip} docker rm #{CONFIG["app"]}-pre-#{vv}-#{index}"
130
+ end
131
+
132
+ deploy_nodes = nodes(CONFIG["deploy"]["constraint"])
133
+
134
+ puts blue("+++ PULL")
135
+ pull_threads = []
136
+ deploy_nodes.each do |node|
137
+ pull_threads << Thread.new do
138
+ host = "#{CONFIG["user"]}@#{node.ip}"
139
+ Open3.popen2e("ssh #{host} docker pull #{CONFIG["registry"]}/#{CONFIG["app"]}:#{hash}") { |i,o,w|
140
+ while line = o.gets do
141
+ puts "[#{node.name}] " + line
142
+ end
143
+ raise "FATAL" unless w.value.success?
144
+ }
145
+ end
146
+ end
147
+ pull_threads.each(&:join)
148
+
149
+ plan = {}
150
+ if CONFIG["deploy"]["per"]
151
+ amount = CONFIG["deploy"]["per"]*deploy_nodes.count
152
+ else
153
+ amount = CONFIG["deploy"]["amount"]
154
+ end
155
+
156
+ amount.times do |index|
157
+ ip = deploy_nodes[index % deploy_nodes.length].ip
158
+ plan[ip] ||= []
159
+ plan[ip].push(index)
160
+ end
161
+
162
+ puts blue("+++ DEPLOY")
163
+ deploy_threads = []
164
+ deploy_nodes.each do |node|
165
+ deploy_threads << Thread.new do
166
+ host = "#{CONFIG["user"]}@#{node.ip}"
167
+
168
+ puts "[#{node.name}] run"
169
+ (plan[node.ip] || []).each do |index|
170
+ port = nil
171
+ 10.times do
172
+ a = MIN_PORT + rand(MAX_PORT - MIN_PORT)
173
+ if just_cmd("ssh #{host} ss -ln src :#{a} | fgrep -c ':#{a}'", true) == "0"
174
+ port = a
175
+ break
176
+ end
177
+ end
178
+ raise "Dont find free port :-((" unless port
179
+ puts "[#{node.name}] port=#{port}"
180
+
181
+ do_it("ssh #{host} docker run -d " +
182
+ "--label app=#{CONFIG["app"]} " +
183
+ "--label service=#{new_service} " +
184
+ "--name=#{CONFIG["app"]}-#{vv}-#{index} " +
185
+ (CONFIG["env"] || {}).map { |k, v| "-e #{k}='#{v}'" }.join(" ") + " " +
186
+ "--restart unless-stopped " +
187
+ "-p #{node.ip}:#{port}:#{CONFIG["deploy"]["port"]} " +
188
+ "#{CONFIG["registry"]}/#{CONFIG["app"]}:#{hash} " +
189
+ "#{CONFIG["deploy"]["cmd"]}")
190
+
191
+ do_it %(curl -s -X PUT #{node.ip}:8500/v1/agent/service/register -d'{
192
+ "Id": "#{CONFIG["app"]}-#{vv}-#{index}",
193
+ "Name": "#{new_service}",
194
+ "Port": #{port},
195
+ "Check": {
196
+ "DeregisterCriticalServiceAfter": "20m",
197
+ "Interval": "7s",
198
+ "HTTP": "http://#{node.ip}:#{port}#{CONFIG["deploy"]["check_url"] || "/"}"
199
+ }
200
+ }')
201
+ end
202
+
203
+ puts blue("+++ CONSUL wait for #{node.name}")
204
+ loop do
205
+ statuses = JSON.load(just_cmd("curl -s #{node.ip}:8500/v1/health/service/#{CONFIG["app"]}-#{vv}")).select { |s|
206
+ s["Node"]["Address"] == node.ip
207
+ }.flat_map { |s| s["Checks"] }.map { |c| c["Status"] }
208
+ puts "#{node.name} => #{statuses.inspect}"
209
+ break if statuses.uniq == ["passing"] or (plan[node.ip] || []).empty?
210
+ sleep 3
211
+ end
212
+ end
213
+ end
214
+ deploy_threads.each(&:join)
215
+
216
+ current_service = just_cmd("curl #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/service?raw")
217
+ current_hash = just_cmd("curl #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/hash?raw")
218
+ puts "CURRENT_SERVICE=#{current_service}"
219
+ puts "CURRENT_HASH=#{current_hash}"
220
+ puts "NEW_SERVICE=#{new_service}"
221
+ do_it "curl -X PUT #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/service -d#{new_service}"
222
+ do_it "curl -X PUT #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/hash -d#{hash}"
223
+ puts "\n\n" + green(">>>>>>>>>>>>>>> BLUE/GREEN switch <<<<<<<<<<<<<<<")
224
+ sleep 3
225
+
226
+ puts blue("+++ STOP OLD containers")
227
+ JSON.load(just_cmd("curl -s #{CONFIG["consul"]}/v1/catalog/services")).keys.select { |service|
228
+ service != new_service && service =~ /^#{CONFIG["app"]}-\d+$/
229
+ }.each do |service|
230
+ JSON.load(just_cmd("curl -s #{CONFIG["consul"]}/v1/health/service/#{service}")).each do |s|
231
+ do_it %(curl -s -X DELETE #{s["Node"]["Address"]}:8500/v1/agent/service/deregister/#{s["Service"]["ID"]})
232
+ end
233
+ end
234
+
235
+ NODES.each do |n|
236
+ keep_ids = just_cmd("ssh #{CONFIG["user"]}@#{n.ip} docker ps -q -f label=app=#{CONFIG["app"]} -f label=service=#{new_service}").split("\n")
237
+ all_ids = just_cmd("ssh #{CONFIG["user"]}@#{n.ip} docker ps -q -f label=app=#{CONFIG["app"]}").split("\n")
238
+ if (all_ids - keep_ids).length > 0
239
+ do_it("ssh #{CONFIG["user"]}@#{n.ip} docker stop #{(all_ids - keep_ids).join(" ")}")
240
+ do_it("ssh #{CONFIG["user"]}@#{n.ip} docker rm #{(all_ids - keep_ids).join(" ")}")
241
+ end
242
+ end
243
+
244
+ puts blue("+++ CLEAN REGISTRY")
245
+ (tags - [hash, current_hash]).each do |hash|
246
+ digest = just_cmd("curl -s --head -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' https://#{CONFIG["registry"]}/v2/#{CONFIG["app"]}/manifests/#{hash} | grep Docker-Content-Digest | cut -d' ' -f2")
247
+ puts "digest = #{digest}"
248
+ system "curl -X DELETE https://#{CONFIG["registry"]}/v2/#{CONFIG["app"]}/manifests/#{digest}"
249
+ end
250
+
251
+ puts green("Done.")
252
+ if current_hash != "" && !target
253
+ puts "to rollback execute: #{$0} #{ARGV[0]} deploy #{current_hash}"
254
+ end
255
+ end
256
+
257
+
258
+ def print_status
259
+ max_name_len = NODES.map { |n| n.name.length }.max
260
+ max_ip_len = NODES.map { |n| n.ip.length }.max
261
+ max_roles_len = NODES.map { |n| n.roles.inspect.length }.max
262
+ current_service = just_cmd("curl -s #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/service?raw")
263
+ current_hash = just_cmd("curl -s #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/hash?raw")
264
+ current_dockers = NODES.map { |n|
265
+ just_cmd("ssh #{CONFIG["user"]}@#{n.ip} 'docker ps -q -f label=app=#{CONFIG["app"]} -f label=service=#{current_service} | wc -l'").to_i
266
+ }
267
+ dockers = NODES.map { |n|
268
+ just_cmd("ssh #{CONFIG["user"]}@#{n.ip} 'docker ps -q -f label=app=#{CONFIG["app"]} | wc -l'").to_i
269
+ }
270
+ puts ""
271
+ puts green("App: ") + CONFIG["app"]
272
+ puts green("Service: ") + current_service
273
+ puts green("Hash: ") + current_hash
274
+ NODES.each_with_index do |n, i|
275
+ puts(
276
+ " "*5 + n.name.rjust(max_name_len) +
277
+ " "*2 + n.ip.ljust(max_ip_len) +
278
+ " "*2 + n.roles.inspect.ljust(max_roles_len) +
279
+ " "*2 + green(current_dockers[i]) + " / " + (dockers[i] - current_dockers[i] == 0 ? "0" : red(dockers[i] - current_dockers[i]))
280
+ )
281
+ end
282
+ end
283
+
284
+
285
+ def do_stop
286
+ current_service = just_cmd("curl -s #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}/service?raw")
287
+ if current_service != ""
288
+ JSON.load(just_cmd("curl -s #{CONFIG["consul"]}/v1/health/service/#{current_service}")).each do |s|
289
+ do_it %(curl -s -X DELETE #{s["Node"]["Address"]}:8500/v1/agent/service/deregister/#{s["Service"]["ID"]})
290
+ end
291
+ end
292
+ NODES.map { |n|
293
+ ids = just_cmd("ssh #{CONFIG["user"]}@#{n.ip} docker ps -q -f label=app=#{CONFIG["app"]}").gsub("\n", " ")
294
+ if ids != ""
295
+ do_it "ssh #{CONFIG["user"]}@#{n.ip} docker stop #{ids}"
296
+ do_it "ssh #{CONFIG["user"]}@#{n.ip} docker rm #{ids}"
297
+ end
298
+ }
299
+ do_it "curl -X DELETE #{CONFIG["consul"]}/v1/kv/apps/#{CONFIG["app"]}?recurse"
300
+ puts ""
301
+ end
302
+
303
+
304
+ if COMMAND == "deploy" || COMMAND == "d"
305
+ deploy(ARGV[2])
306
+ elsif COMMAND == "status" || COMMAND == "s"
307
+ print_status
308
+ elsif COMMAND == "stop"
309
+ do_stop
310
+ else
311
+ puts "FATAL: unknown command '#{COMMAND}'"
312
+ end
313
+
data/lib/app-rb/cli.rb ADDED
@@ -0,0 +1,4 @@
1
+ module AppRb
2
+ class Cli
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module AppRb
2
+ VERSION = "0.1.0"
3
+ end
data/lib/app-rb.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "app-rb/version"
2
+ require "app-rb/cli"
3
+
4
+ module AppRb
5
+ def self.get_version
6
+ VERSION
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: app-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexey Vakhov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Deploy docker apps. Nothing else
56
+ email:
57
+ - vakhov@gmail.com
58
+ executables:
59
+ - app-rb
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - app-rb.gemspec
72
+ - bin/release
73
+ - exe/app-rb
74
+ - lib/app-rb.rb
75
+ - lib/app-rb/cli.rb
76
+ - lib/app-rb/version.rb
77
+ homepage: https://github.com/uchiru/app-rb
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.5.2
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Easy deploy docker apps
101
+ test_files: []