app-rb 0.1.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 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: []