docker_toolkit 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 +7 -0
- data/.dockerignore +20 -0
- data/.gitignore +109 -0
- data/.rspec +4 -0
- data/.rubocop.yml +89 -0
- data/.travis.yml +12 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +59 -0
- data/README.md +4 -0
- data/bin/consul.rb +222 -0
- data/bin/merger.rb +116 -0
- data/bin/waiter.rb +246 -0
- data/docker/Dockerfile +53 -0
- data/docker/docker-compose.yml +12 -0
- data/docker/down.sh +4 -0
- data/docker/run_tests.sh +17 -0
- data/docker_toolkit.gemspec +33 -0
- data/lib/docker_toolkit/version.rb +5 -0
- data/lib/docker_toolkit.rb +10 -0
- metadata +122 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8bed7bfd3321be850470d15839c3e4516c030ef2fd85a5cb893719e69651235c
|
|
4
|
+
data.tar.gz: bca92e12468219f060491956acc7d1867c198e43b9f933a08351ee0929fd5ffd
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5146180b05f18e8ba0a42da96465c3aefaf3a671b3d9b396dabb184eda42023c86df8ba6320f279962711f743eb16ea7e4fdfa781ac4caa60065199d1dea8ebd
|
|
7
|
+
data.tar.gz: a6776d22bbc35be6b0283cb0ee730c8eb9addb16063e8acdb3d8258d95f75f78ebb13fa62178f46a25f3744e46d9ebe187074556882d1d74fe71aadafd1f97ee
|
data/.dockerignore
ADDED
data/.gitignore
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
|
2
|
+
#
|
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
|
6
|
+
|
|
7
|
+
# bundler state
|
|
8
|
+
/.bundle
|
|
9
|
+
vendor/cache
|
|
10
|
+
vendor/bundle
|
|
11
|
+
/vendor/ruby/
|
|
12
|
+
|
|
13
|
+
# minimal Rails specific artifacts
|
|
14
|
+
db/*.sqlite3
|
|
15
|
+
/db/*.sqlite3-journal
|
|
16
|
+
/log/*
|
|
17
|
+
/tmp/*
|
|
18
|
+
|
|
19
|
+
# add /config/database.yml if it contains passwords
|
|
20
|
+
# /config/database.yml
|
|
21
|
+
|
|
22
|
+
# various artifacts
|
|
23
|
+
**.war
|
|
24
|
+
*.rbc
|
|
25
|
+
*.sassc
|
|
26
|
+
.redcar/
|
|
27
|
+
.sass-cache
|
|
28
|
+
/config/config.yml
|
|
29
|
+
/coverage.data
|
|
30
|
+
/coverage/
|
|
31
|
+
/db/*.javadb/
|
|
32
|
+
/db/*.sqlite3
|
|
33
|
+
/config/database.yml
|
|
34
|
+
/config/secrets.yml
|
|
35
|
+
oxymoron.js
|
|
36
|
+
/doc/api/
|
|
37
|
+
/doc/app/
|
|
38
|
+
/doc/features.html
|
|
39
|
+
/doc/specs.html
|
|
40
|
+
/public/cache
|
|
41
|
+
/public/uploads
|
|
42
|
+
/public/stylesheets/compiled
|
|
43
|
+
/public/system/*
|
|
44
|
+
/spec/tmp/*
|
|
45
|
+
/cache
|
|
46
|
+
/capybara*
|
|
47
|
+
/capybara-*.html
|
|
48
|
+
/gems
|
|
49
|
+
/specifications
|
|
50
|
+
app/assets/fonts/disp-preview.html
|
|
51
|
+
rerun.txt
|
|
52
|
+
pickle-email-*.html
|
|
53
|
+
*.sublime-project
|
|
54
|
+
*.sublime-workspace
|
|
55
|
+
.zeus.sock
|
|
56
|
+
.byebug_history
|
|
57
|
+
|
|
58
|
+
#test
|
|
59
|
+
/docs
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
|
63
|
+
# or operating system, you probably want to add a global ignore instead:
|
|
64
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
|
65
|
+
#
|
|
66
|
+
# Here are some files you may want to ignore globally:
|
|
67
|
+
|
|
68
|
+
# scm revert files
|
|
69
|
+
**.orig
|
|
70
|
+
|
|
71
|
+
# Mac finder artifacts
|
|
72
|
+
.DS_Store
|
|
73
|
+
|
|
74
|
+
# Netbeans project directory
|
|
75
|
+
/nbproject/
|
|
76
|
+
|
|
77
|
+
# RubyMine project files
|
|
78
|
+
.idea
|
|
79
|
+
|
|
80
|
+
# Textmate project files
|
|
81
|
+
/*.tmproj
|
|
82
|
+
|
|
83
|
+
# vim artifacts
|
|
84
|
+
**.swp
|
|
85
|
+
|
|
86
|
+
# Environment files that may contain sensitive data
|
|
87
|
+
.env
|
|
88
|
+
.powenv
|
|
89
|
+
|
|
90
|
+
# tilde files are usually backup files from a text editor
|
|
91
|
+
*~
|
|
92
|
+
public/assets/
|
|
93
|
+
config/keys
|
|
94
|
+
.ruby-gemset
|
|
95
|
+
.ruby-version
|
|
96
|
+
spec/reports/
|
|
97
|
+
app/assets/javascripts/oxymoron.js
|
|
98
|
+
|
|
99
|
+
!/log/.keep
|
|
100
|
+
!/tmp/.keep
|
|
101
|
+
|
|
102
|
+
/node_modules
|
|
103
|
+
/yarn-error.log
|
|
104
|
+
|
|
105
|
+
.byebug_history
|
|
106
|
+
/public/packs
|
|
107
|
+
/public/packs-test
|
|
108
|
+
/node_modules
|
|
109
|
+
passenger.*.pid.lock
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 2.5
|
|
3
|
+
Exclude:
|
|
4
|
+
- 'storage/**/*'
|
|
5
|
+
- 'docker/**/*'
|
|
6
|
+
|
|
7
|
+
Style/AsciiComments:
|
|
8
|
+
Enabled: false
|
|
9
|
+
|
|
10
|
+
Style/RedundantBegin:
|
|
11
|
+
Enabled: false
|
|
12
|
+
|
|
13
|
+
Style/GlobalVars:
|
|
14
|
+
AllowedVariables: ['$logger', '$root']
|
|
15
|
+
|
|
16
|
+
Metrics/BlockLength:
|
|
17
|
+
Exclude:
|
|
18
|
+
- 'spec/**/*.rb'
|
|
19
|
+
|
|
20
|
+
Metrics/MethodLength:
|
|
21
|
+
Max: 20
|
|
22
|
+
|
|
23
|
+
Style/ClassAndModuleChildren:
|
|
24
|
+
EnforcedStyle: compact
|
|
25
|
+
Enabled: false
|
|
26
|
+
|
|
27
|
+
Style/Documentation:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
Style/Lambda:
|
|
31
|
+
Enabled: false
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Style/RaiseArgs:
|
|
35
|
+
EnforcedStyle: compact
|
|
36
|
+
|
|
37
|
+
Metrics/LineLength:
|
|
38
|
+
Max: 100
|
|
39
|
+
|
|
40
|
+
#Layout/IndentationWidth:
|
|
41
|
+
# Enabled: true
|
|
42
|
+
|
|
43
|
+
#Layout/IndentAssignment:
|
|
44
|
+
# Enabled: false
|
|
45
|
+
# IndentationWidth: false
|
|
46
|
+
|
|
47
|
+
#Layout/ElseAlignment:
|
|
48
|
+
# Enabled: false
|
|
49
|
+
|
|
50
|
+
#Layout/EndAlignment:
|
|
51
|
+
# Enabled: false
|
|
52
|
+
|
|
53
|
+
#Lint/AssignmentInCondition:
|
|
54
|
+
# Enabled: false
|
|
55
|
+
|
|
56
|
+
Layout/IndentationConsistency:
|
|
57
|
+
EnforcedStyle: rails
|
|
58
|
+
|
|
59
|
+
Layout/EmptyLines:
|
|
60
|
+
Enabled: false
|
|
61
|
+
|
|
62
|
+
Layout/EmptyLinesAroundClassBody:
|
|
63
|
+
EnforcedStyle: empty_lines
|
|
64
|
+
|
|
65
|
+
Layout/EmptyLinesAroundModuleBody:
|
|
66
|
+
EnforcedStyle: empty_lines
|
|
67
|
+
|
|
68
|
+
Layout/SpaceInsideBlockBraces:
|
|
69
|
+
EnforcedStyle: space
|
|
70
|
+
SpaceBeforeBlockParameters: false
|
|
71
|
+
|
|
72
|
+
Layout/SpaceAroundBlockParameters:
|
|
73
|
+
EnforcedStyleInsidePipes: no_space
|
|
74
|
+
|
|
75
|
+
Layout/SpaceBeforeBlockBraces:
|
|
76
|
+
Enabled: false
|
|
77
|
+
|
|
78
|
+
Style/NumericPredicate:
|
|
79
|
+
Enabled: false
|
|
80
|
+
|
|
81
|
+
Style/FrozenStringLiteralComment:
|
|
82
|
+
Enabled: false
|
|
83
|
+
|
|
84
|
+
Style/DoubleNegation:
|
|
85
|
+
Enabled: false
|
|
86
|
+
|
|
87
|
+
Style/SymbolArray:
|
|
88
|
+
Enabled: false
|
|
89
|
+
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
docker_toolkit (0.1.0)
|
|
5
|
+
diplomat
|
|
6
|
+
json
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
awesome_print (1.8.0)
|
|
12
|
+
concurrent-ruby (1.0.5)
|
|
13
|
+
diff-lcs (1.3)
|
|
14
|
+
diplomat (2.0.2)
|
|
15
|
+
faraday (~> 0.9)
|
|
16
|
+
json
|
|
17
|
+
faker (1.9.1)
|
|
18
|
+
i18n (>= 0.7)
|
|
19
|
+
faker-russian (0.0.6)
|
|
20
|
+
faraday (0.15.2)
|
|
21
|
+
multipart-post (>= 1.2, < 3)
|
|
22
|
+
i18n (1.0.1)
|
|
23
|
+
concurrent-ruby (~> 1.0)
|
|
24
|
+
json (2.1.0)
|
|
25
|
+
multipart-post (2.0.0)
|
|
26
|
+
rake (10.5.0)
|
|
27
|
+
rspec (3.7.0)
|
|
28
|
+
rspec-core (~> 3.7.0)
|
|
29
|
+
rspec-expectations (~> 3.7.0)
|
|
30
|
+
rspec-mocks (~> 3.7.0)
|
|
31
|
+
rspec-core (3.7.1)
|
|
32
|
+
rspec-support (~> 3.7.0)
|
|
33
|
+
rspec-expectations (3.7.0)
|
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
35
|
+
rspec-support (~> 3.7.0)
|
|
36
|
+
rspec-mocks (3.7.0)
|
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
|
+
rspec-support (~> 3.7.0)
|
|
39
|
+
rspec-retry (0.6.1)
|
|
40
|
+
rspec-core (> 3.3)
|
|
41
|
+
rspec-set (0.1.3)
|
|
42
|
+
rspec-support (3.7.1)
|
|
43
|
+
|
|
44
|
+
PLATFORMS
|
|
45
|
+
ruby
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
awesome_print
|
|
49
|
+
bundler (~> 1.14)
|
|
50
|
+
docker_toolkit!
|
|
51
|
+
faker
|
|
52
|
+
faker-russian
|
|
53
|
+
rake (~> 10.0)
|
|
54
|
+
rspec
|
|
55
|
+
rspec-retry
|
|
56
|
+
rspec-set
|
|
57
|
+
|
|
58
|
+
BUNDLED WITH
|
|
59
|
+
1.16.1
|
data/README.md
ADDED
data/bin/consul.rb
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'diplomat'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require 'English'
|
|
6
|
+
require 'yaml'
|
|
7
|
+
|
|
8
|
+
STDOUT.sync = true
|
|
9
|
+
STDERR.sync = true
|
|
10
|
+
|
|
11
|
+
@opts = {}
|
|
12
|
+
|
|
13
|
+
@opts[:exec] = (begin
|
|
14
|
+
ARGV.join(' ').split(' -- ')[1].strip
|
|
15
|
+
rescue StandardError
|
|
16
|
+
nil
|
|
17
|
+
end)
|
|
18
|
+
|
|
19
|
+
parser = OptionParser.new do |o|
|
|
20
|
+
o.banner = 'Usage: consul.rb [options] -- exec'
|
|
21
|
+
|
|
22
|
+
o.on('--consul url', 'Set up a custom Consul URL') do |url|
|
|
23
|
+
Diplomat.configure do |config|
|
|
24
|
+
config.url = url.strip
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
o.on('--token token', 'Connect into consul with custom access token (ACL)') do |token|
|
|
29
|
+
Diplomat.configure do |config|
|
|
30
|
+
config.acl_token = token.strip
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
o.on('--init [service]', 'Initialize Consul services from config') do |service|
|
|
35
|
+
@opts[:service] = service
|
|
36
|
+
@opts[:init] = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
o.on('--config file', 'Read service configulation from file') do |file|
|
|
40
|
+
@opts[:config] = file.strip
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
o.on('--upload', 'Upload files to variables') do
|
|
44
|
+
@opts[:upload] = true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
o.on('--show [service]', 'Show service configulation from Consul') do |service|
|
|
48
|
+
@opts[:service] = service
|
|
49
|
+
@opts[:show] = true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
o.on('--override', 'override existed keys') do
|
|
53
|
+
@opts[:override] = true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
o.on('-d', '--dereference', 'dereference consul values in form of "consul://key/subkey"') do
|
|
57
|
+
@opts[:dereference] = true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
o.on('--env prefix', 'export KV values from prefix as env varaibles') do |prefix|
|
|
61
|
+
@opts[:env] = (prefix + '/').gsub('//', '/')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
o.on('--export', 'add export to --env output') do
|
|
65
|
+
@opts[:export] = true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
o.on('--pristine', "not include the parent processes' environment when exec child process") do
|
|
69
|
+
@opts[:pristine] = true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
o.on('--put path:value', 'put value to path') do |path|
|
|
73
|
+
@opts[:put] = path.strip
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
o.on('--get path', 'get value from') do |path|
|
|
77
|
+
@opts[:get] = path.strip
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
parser.parse!
|
|
81
|
+
|
|
82
|
+
def die(message)
|
|
83
|
+
STDERR.puts "Error: #{message}"
|
|
84
|
+
exit 1
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def key_to_consul(key)
|
|
88
|
+
key.downcase.gsub(/[^0-9a-z]/i, '_')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def key_to_env(key)
|
|
92
|
+
key.upcase.gsub(/[^0-9a-z]/i, '_')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def dereferenced_value(value)
|
|
96
|
+
if @opts[:dereference] && value && value[/^consul:\/\//]
|
|
97
|
+
reference_path = value.gsub(/^consul:\/\//, '')
|
|
98
|
+
dereferenced_value(Diplomat::Kv.get(reference_path))
|
|
99
|
+
else
|
|
100
|
+
value
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if config = @opts[:config]
|
|
105
|
+
@opts[:config] = YAML.safe_load(config == '-' ? STDIN.read : File.read(config), [], [], true)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if @opts[:init]
|
|
109
|
+
raise OptionParser::MissingArgument.new('config') unless @opts[:config]
|
|
110
|
+
|
|
111
|
+
services = if service = @opts[:service]
|
|
112
|
+
{
|
|
113
|
+
service => @opts[:config][service]
|
|
114
|
+
}
|
|
115
|
+
else
|
|
116
|
+
@opts[:config]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
services.each_pair do |service, config|
|
|
120
|
+
next unless config
|
|
121
|
+
next if service[/^\./] # skip hidden keys
|
|
122
|
+
|
|
123
|
+
path = "services/env/#{service}"
|
|
124
|
+
config.each_pair do |env, item|
|
|
125
|
+
key = "#{path}/#{key_to_consul(env)}"
|
|
126
|
+
value = if @opts[:upload] && item['file']
|
|
127
|
+
File.read(item['file'])
|
|
128
|
+
else
|
|
129
|
+
item['value'] || item['default'] || item['file']
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
empty = begin
|
|
133
|
+
Diplomat::Kv.get(key)
|
|
134
|
+
false
|
|
135
|
+
rescue Diplomat::KeyNotFound
|
|
136
|
+
true
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
Diplomat::Kv.put(key, value.to_s.strip) || die("Can't put #{key} to Consul") if empty || @opts[:override]
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
exit 0
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if @opts[:show]
|
|
147
|
+
config = {}
|
|
148
|
+
|
|
149
|
+
path = if service = @opts[:service]
|
|
150
|
+
"services/env/#{service}/"
|
|
151
|
+
else
|
|
152
|
+
'services/env/'
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
answer = Diplomat::Kv.get(path, recurse: true, convert_to_hash: true) || die("Can't get #{path} from Consul")
|
|
156
|
+
answer['services']['env'].each_pair do |service, env|
|
|
157
|
+
cfg = config[service] ||= {}
|
|
158
|
+
|
|
159
|
+
env.each_pair do |key, value|
|
|
160
|
+
value = dereferenced_value(value)
|
|
161
|
+
|
|
162
|
+
cfg[key_to_env(key)] = {
|
|
163
|
+
env: key_to_env(key),
|
|
164
|
+
value: value
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
STDOUT.puts JSON.parse(config.to_json).to_yaml
|
|
170
|
+
|
|
171
|
+
exit 0
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
if put = @opts[:put]
|
|
175
|
+
path, *value = put.split(':').map(&:strip)
|
|
176
|
+
value = value.join(':')
|
|
177
|
+
value = File.read(value) if @opts[:upload] && value && File.exist?(value)
|
|
178
|
+
|
|
179
|
+
Diplomat::Kv.put(path, value.to_s.strip) || die("Can't put #{path} to Consul")
|
|
180
|
+
|
|
181
|
+
exit 0
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
if path = @opts[:get]
|
|
185
|
+
value = dereferenced_value(Diplomat::Kv.get(path))
|
|
186
|
+
|
|
187
|
+
STDOUT.puts value.to_s.strip
|
|
188
|
+
|
|
189
|
+
exit 0
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
if prefix = @opts[:env]
|
|
193
|
+
keys = begin
|
|
194
|
+
Diplomat::Kv.get(prefix, keys: true)
|
|
195
|
+
rescue Diplomat::KeyNotFound => e
|
|
196
|
+
[]
|
|
197
|
+
rescue StandardError
|
|
198
|
+
die("Can't get keys at #{prefix} from Consul")
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
env = keys.reduce({}) do |e, key|
|
|
202
|
+
value = dereferenced_value(Diplomat::Kv.get(key))
|
|
203
|
+
|
|
204
|
+
e.merge(key_to_env(key.gsub(prefix, '')) => value)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
if cmd = @opts[:exec]
|
|
208
|
+
env = ENV.to_h.merge(env) unless @opts[:pristine]
|
|
209
|
+
|
|
210
|
+
exec(env, cmd, unsetenv_others: true)
|
|
211
|
+
else
|
|
212
|
+
env.each_pair do |k, v|
|
|
213
|
+
STDOUT.puts "#{@opts[:export] ? 'export ' : ''}#{k}=\"#{v}\""
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
exit 0
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
STDOUT.puts parser.help
|
|
222
|
+
exit 1
|
data/bin/merger.rb
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'English'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
|
|
6
|
+
if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
|
|
7
|
+
unless ENV['COMPOSE_FILE']
|
|
8
|
+
STDERR.puts 'COMPOSE_FILE environment must point to one on mo files'
|
|
9
|
+
exit 1
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Hash
|
|
15
|
+
|
|
16
|
+
def deep_dup
|
|
17
|
+
Marshal.load(Marshal.dump(self))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Array
|
|
23
|
+
|
|
24
|
+
def deep_dup
|
|
25
|
+
Marshal.load(Marshal.dump(self))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def extend_hash(first, second)
|
|
33
|
+
raise ArgumentError.new('First and second args equal nil') if [first, second].all? &:nil?
|
|
34
|
+
return second if first.nil?
|
|
35
|
+
return first if second.nil?
|
|
36
|
+
|
|
37
|
+
first.each_pair do |fk, fv|
|
|
38
|
+
next unless second.key?(fk)
|
|
39
|
+
|
|
40
|
+
sv = second[fk]
|
|
41
|
+
raise "Types of values not match(#{fv.class}, #{sv.class})" if fv.class != sv.class
|
|
42
|
+
|
|
43
|
+
# Специальный случай потому что command не мерджится а заменяется
|
|
44
|
+
if fk == 'command'
|
|
45
|
+
first[fk] = sv
|
|
46
|
+
elsif fv.is_a? Hash
|
|
47
|
+
extend_hash(fv, sv)
|
|
48
|
+
elsif fv.is_a? Array
|
|
49
|
+
fv |= sv
|
|
50
|
+
first[fk] = fv
|
|
51
|
+
else
|
|
52
|
+
first[fk] = sv
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
second.each_pair do |sk, sv|
|
|
57
|
+
next if first.key?(sk)
|
|
58
|
+
|
|
59
|
+
first[sk] = sv
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
first
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def process_compose_hash(yml, dirname, parent = {})
|
|
66
|
+
(yml['services'] || {}).each_pair do |name, service|
|
|
67
|
+
next unless ext = service['extends']
|
|
68
|
+
base = if ext.is_a? String
|
|
69
|
+
template = yml['services'][ext]
|
|
70
|
+
parent_service = (parent['services'] || {})[ext] || {}
|
|
71
|
+
extend_hash(parent_service.deep_dup, template)
|
|
72
|
+
elsif file = ext['file']
|
|
73
|
+
ENV.each_pair do |k, v|
|
|
74
|
+
file.gsub!("$#{k}", v)
|
|
75
|
+
file.gsub!("${#{k}}", v)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
tmp = if File.exist?(dirname + '/' + file)
|
|
79
|
+
YAML.safe_load(File.read(dirname + '/' + file))
|
|
80
|
+
else
|
|
81
|
+
YAML.safe_load(File.read(file))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
begin
|
|
85
|
+
(tmp['services'][ext['service']] || {})
|
|
86
|
+
rescue StandardError
|
|
87
|
+
{}
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
yml['services'][ext['service']]
|
|
91
|
+
end.deep_dup
|
|
92
|
+
|
|
93
|
+
service.delete 'extends'
|
|
94
|
+
|
|
95
|
+
yml['services'][name] = extend_hash(base, service)
|
|
96
|
+
end
|
|
97
|
+
yml
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
|
|
101
|
+
result = ENV['COMPOSE_FILE'].split(':').reduce({}) do |parent, file|
|
|
102
|
+
yml = process_compose_hash(YAML.safe_load(File.read(file)), File.dirname(file), parent)
|
|
103
|
+
if yml['version'] && parent['version'] && yml['version'] != parent['version']
|
|
104
|
+
raise "version mismatch: #{file}"
|
|
105
|
+
end
|
|
106
|
+
ret = extend_hash(parent.deep_dup, yml)
|
|
107
|
+
ret
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if ARGV[0].nil? || ARGV[0].strip == '-'
|
|
111
|
+
puts YAML.dump(result)
|
|
112
|
+
else
|
|
113
|
+
File.write(ARGV[0].strip, YAML.dump(result))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
data/bin/waiter.rb
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
require 'securerandom'
|
|
5
|
+
require 'English'
|
|
6
|
+
require 'openssl'
|
|
7
|
+
require 'tempfile'
|
|
8
|
+
|
|
9
|
+
STDOUT.sync = true
|
|
10
|
+
STDERR.sync = true
|
|
11
|
+
|
|
12
|
+
TIMEOUT = 15
|
|
13
|
+
INTERVAL = 3
|
|
14
|
+
|
|
15
|
+
@opts = {}
|
|
16
|
+
|
|
17
|
+
@opts[:exec] = (begin
|
|
18
|
+
ARGV.join(' ').split(' -- ')[1].strip
|
|
19
|
+
rescue StandardError
|
|
20
|
+
nil
|
|
21
|
+
end)
|
|
22
|
+
@opts[:timeout] = TIMEOUT
|
|
23
|
+
@opts[:interval] = INTERVAL
|
|
24
|
+
@opts[:consul_addr] = 'http://localhost:8500'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
OptionParser.new do |o|
|
|
28
|
+
o.banner = 'Usage: waiter.rb [options] -- exec'
|
|
29
|
+
|
|
30
|
+
o.on('--tcp host:port', 'Wait for tcp accepts on host:port') do |addr|
|
|
31
|
+
host, port = addr.split(':')
|
|
32
|
+
@opts[:tcp] = addr.strip
|
|
33
|
+
@opts[:host] = host.strip
|
|
34
|
+
@opts[:port] = port.strip
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
o.on('--db dbname', 'Wait for PG database exists. Using --tcp to conenct PG') do |db|
|
|
38
|
+
@opts[:db] = db.strip
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
o.on('--tb tablename', 'Wait for PG table exists. Using --tcp to conenct PG') do |tb|
|
|
42
|
+
@opts[:tb] = tb.strip
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
o.on('-f', '--file filename', 'Wait for file exists.') do |file|
|
|
46
|
+
@opts[:file] = file.strip
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
o.on("--consul-addr addr=#{@opts[:consul_addr]}", 'HTTP addres to connect to consul') do |addr|
|
|
50
|
+
@opts[:consul_addr] = addr.strip
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
o.on('--consul', 'Wait for local consul agent to be ready') do
|
|
54
|
+
@opts[:consul] = true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
o.on('--consul-service service', 'Wait for service appear in consul') do |service|
|
|
58
|
+
@opts[:consul_service] = service
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
o.on('--user user', 'username') do |user|
|
|
62
|
+
@opts[:user] = user.strip
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
o.on('--pass pass', 'password') do |pass|
|
|
66
|
+
@opts[:pass] = pass.strip
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
o.on('-t', '--timeout secs=15', 'Total timeout') do |timeout|
|
|
70
|
+
@opts[:timeout] = timeout.to_i
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
o.on('-i', '--interval secs=2', 'Interval between attempts') do |interval|
|
|
74
|
+
@opts[:interval] = interval.to_i
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
o.on('-q', '--quiet', 'Do not output any status messages') do
|
|
78
|
+
@opts[:quiet] = true
|
|
79
|
+
end
|
|
80
|
+
end.parse!
|
|
81
|
+
|
|
82
|
+
def log(message)
|
|
83
|
+
puts message unless @opts[:quiet]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
@opts[:timeout] = @opts[:timeout].to_i
|
|
87
|
+
@opts[:interval] = @opts[:interval].to_i
|
|
88
|
+
|
|
89
|
+
if @opts[:db]
|
|
90
|
+
@pg = {}
|
|
91
|
+
@pg[:db] = "-d #{@opts[:db]}"
|
|
92
|
+
@pg[:user] = "-U #{@opts[:user]}" if @opts[:user]
|
|
93
|
+
@pg[:pass] = if @opts[:pass] && !@opts[:pass].empty?
|
|
94
|
+
"-W #{@opts[:pass]}"
|
|
95
|
+
else
|
|
96
|
+
'-w'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@pg[:host] = "-h #{@opts[:host]}" if @opts[:host]
|
|
100
|
+
@pg[:port] = "-p #{@opts[:port]}" if @opts[:port]
|
|
101
|
+
|
|
102
|
+
@pg[:tb] = @opts[:tb] if @opts[:tb]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def wait_for(timeout)
|
|
106
|
+
starttime = Time.now
|
|
107
|
+
loop do
|
|
108
|
+
success = yield
|
|
109
|
+
|
|
110
|
+
return success if success
|
|
111
|
+
|
|
112
|
+
return false if (Time.now - starttime) > timeout
|
|
113
|
+
sleep @opts[:interval]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
false
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def complete!(success)
|
|
120
|
+
if success
|
|
121
|
+
if @opts[:exec]
|
|
122
|
+
exec @opts[:exec]
|
|
123
|
+
else
|
|
124
|
+
exit 0
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
STDERR.puts 'Operation timed out'
|
|
129
|
+
exit 1
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def wait_for_consul
|
|
133
|
+
log('Waiting for consul...')
|
|
134
|
+
ret = wait_for @opts[:timeout] do
|
|
135
|
+
cmd = "consul operator raft list-peers -http-addr=#{@opts[:consul_addr]} > /dev/null 2>&1"
|
|
136
|
+
system(cmd)
|
|
137
|
+
$CHILD_STATUS.success?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
yield(ret)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def wait_for_consul_service(service)
|
|
144
|
+
log("Waiting for consul service #{service}...")
|
|
145
|
+
ret = wait_for @opts[:timeout] do
|
|
146
|
+
cmd = "curl -s #{@opts[:consul_addr]}/v1/health/service/#{service}?passing | wc -c"
|
|
147
|
+
bytes = `#{cmd}`.to_i
|
|
148
|
+
bytes > 10
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
yield(ret)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def wait_for_tcp
|
|
155
|
+
log("Waiting for TCP: #{@opts[:host]}:#{@opts[:port]}...")
|
|
156
|
+
ret = wait_for @opts[:timeout] do
|
|
157
|
+
cmd = "nc -z #{@opts[:host]} #{@opts[:port]} > /dev/null 2>&1"
|
|
158
|
+
system(cmd)
|
|
159
|
+
$CHILD_STATUS.success?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
yield(ret)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def wait_for_db
|
|
166
|
+
log("Waiting for DB: pg://#{@opts[:user]}:#{@opts[:pass]}@#{@opts[:host]}:#{@opts[:port]}/#{@opts[:db]}...")
|
|
167
|
+
ret = wait_for @opts[:timeout] do
|
|
168
|
+
cmd = "psql -lqt #{@pg[:user]} #{@pg[:pass]} #{@pg[:host]} #{@pg[:port]} #{@pg[:db]} 2>/dev/null | cut -d \\| -f 1 | grep -qw #{@opts[:db]} > /dev/null 2>&1"
|
|
169
|
+
system(cmd)
|
|
170
|
+
$CHILD_STATUS.success?
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
yield(ret)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def wait_for_tb
|
|
177
|
+
log("Waiting for TABLE: pg://#{@opts[:user]}:#{@opts[:pass]}@#{@opts[:host]}:#{@opts[:port]}/#{@opts[:db]}##{@opts[:tb]}...")
|
|
178
|
+
ret = wait_for @opts[:timeout] do
|
|
179
|
+
cmd = "echo \"\\dt\" | psql -qt #{@pg[:user]} #{@pg[:pass]} #{@pg[:host]} #{@pg[:port]} #{@pg[:db]} 2>/dev/null | cut -d \\| -f 2 | grep -qw #{@pg[:tb]} > /dev/null 2>&1"
|
|
180
|
+
system(cmd)
|
|
181
|
+
$CHILD_STATUS.success?
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
yield(ret)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def wait_for_file(file = @opts[:file], timeout = @opts[:timeout])
|
|
188
|
+
log("Waiting for FILE: #{file}")
|
|
189
|
+
ret = wait_for timeout do
|
|
190
|
+
File.exist? file
|
|
191
|
+
end
|
|
192
|
+
yield(ret)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
if @opts[:tb]
|
|
196
|
+
wait_for_tcp do |success|
|
|
197
|
+
if success
|
|
198
|
+
wait_for_db do |success|
|
|
199
|
+
if success
|
|
200
|
+
wait_for_tb do |success|
|
|
201
|
+
complete!(success)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
complete!(false)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
if @opts[:db]
|
|
212
|
+
wait_for_tcp do |success|
|
|
213
|
+
if success
|
|
214
|
+
wait_for_db do |success|
|
|
215
|
+
complete!(success)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
complete!(false)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
if @opts[:consul]
|
|
225
|
+
wait_for_consul do |success|
|
|
226
|
+
complete!(success)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
if @opts[:consul_service]
|
|
231
|
+
wait_for_consul_service(@opts[:consul_service]) do |success|
|
|
232
|
+
complete!(success)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
if @opts[:tcp]
|
|
237
|
+
wait_for_tcp do |success|
|
|
238
|
+
complete!(success)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
if @opts[:file]
|
|
243
|
+
wait_for_file(@opts[:file], @opts[:timeout]) do |success|
|
|
244
|
+
complete!(success)
|
|
245
|
+
end
|
|
246
|
+
end
|
data/docker/Dockerfile
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
FROM ruby:2.5.0-alpine
|
|
2
|
+
MAINTAINER Firmhouse "kinnalru@gmail.com"
|
|
3
|
+
|
|
4
|
+
WORKDIR /home/app
|
|
5
|
+
|
|
6
|
+
RUN mkdir -p ~/.ssh && echo -e "Host * \
|
|
7
|
+
\n StrictHostKeyChecking no \
|
|
8
|
+
\n UserKnownHostsFile=/dev/null\n" >> ~/.ssh/config
|
|
9
|
+
|
|
10
|
+
RUN set -ex \
|
|
11
|
+
&& apk add --no-cache \
|
|
12
|
+
bash \
|
|
13
|
+
libstdc++ \
|
|
14
|
+
libxml2 \
|
|
15
|
+
ruby-libs \
|
|
16
|
+
wget \
|
|
17
|
+
curl \
|
|
18
|
+
libcurl \
|
|
19
|
+
ruby \
|
|
20
|
+
git \
|
|
21
|
+
tzdata
|
|
22
|
+
|
|
23
|
+
RUN set -ex \
|
|
24
|
+
&& curl -sSLo /tmp/consul.zip https://releases.hashicorp.com/consul/1.2.1/consul_1.2.1_linux_amd64.zip \
|
|
25
|
+
&& unzip -d /bin /tmp/consul.zip \
|
|
26
|
+
&& rm -rf /tmp/consul.zip \
|
|
27
|
+
&& addgroup consul \
|
|
28
|
+
&& adduser -D -g "" -s /bin/sh -G consul consul \
|
|
29
|
+
&& mkdir -p /tmp/consul \
|
|
30
|
+
&& chown -R consul:consul /tmp/consul
|
|
31
|
+
|
|
32
|
+
RUN set -ex \
|
|
33
|
+
&& curl -so envconsul.tgz https://releases.hashicorp.com/envconsul/0.7.3/envconsul_0.7.3_linux_amd64.tgz \
|
|
34
|
+
&& tar -xvzf envconsul.tgz \
|
|
35
|
+
&& rm -rf envconsul.tgz \
|
|
36
|
+
&& mv envconsul /bin/envconsul \
|
|
37
|
+
&& chmod +x /bin/envconsul
|
|
38
|
+
|
|
39
|
+
ADD Gemfile Gemfile.lock docker_toolkit.gemspec /home/app/
|
|
40
|
+
ADD lib/ /home/app/lib
|
|
41
|
+
|
|
42
|
+
RUN set -ex \
|
|
43
|
+
&& bundle install \
|
|
44
|
+
&& cd / \
|
|
45
|
+
&& rm -rf /usr/src/ruby
|
|
46
|
+
|
|
47
|
+
ADD . /home/app
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
SHELL ["/bin/sh", "-c", "-l"]
|
|
52
|
+
|
|
53
|
+
|
data/docker/down.sh
ADDED
data/docker/run_tests.sh
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
SELF=$(readlink -f $0)
|
|
3
|
+
export ENV_ROOT=$(dirname "${SELF}")
|
|
4
|
+
|
|
5
|
+
trap '$ENV_ROOT/down.sh' EXIT
|
|
6
|
+
|
|
7
|
+
cd $ENV_ROOT
|
|
8
|
+
|
|
9
|
+
docker-compose up -d --force-recreate --build || exit 1
|
|
10
|
+
docker-compose exec -T tests bundle exec rspec $@
|
|
11
|
+
|
|
12
|
+
code=$?
|
|
13
|
+
if [ $code -ne 0 ]; then
|
|
14
|
+
docker-compose logs
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
exit $code
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require 'docker_toolkit/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'docker_toolkit'
|
|
7
|
+
spec.version = DockerToolkit::VERSION
|
|
8
|
+
spec.authors = ['Godko Ivan', 'Samoilenko Yuri']
|
|
9
|
+
spec.email = ['igodko@rnds.pro', 'kinnalru@gmail.com']
|
|
10
|
+
spec.homepage = 'https://github.com/RnD-Soft/docker_toolkit'
|
|
11
|
+
spec.required_ruby_version = '>= 2.1.0'
|
|
12
|
+
|
|
13
|
+
spec.summary = 'Helper scripts for work with docker and consul'
|
|
14
|
+
spec.description = 'Advanced docker and consul control scripts'
|
|
15
|
+
|
|
16
|
+
spec.bindir = 'bin'
|
|
17
|
+
spec.require_paths = ['lib']
|
|
18
|
+
|
|
19
|
+
if File.exist?(File.join(__dir__, '/', '.git'))
|
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
21
|
+
f.match(%r{^(test|spec|features)/})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
spec.add_dependency 'diplomat'
|
|
29
|
+
spec.add_dependency 'json'
|
|
30
|
+
|
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
|
32
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
33
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: docker_toolkit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Godko Ivan
|
|
8
|
+
- Samoilenko Yuri
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2018-08-10 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: diplomat
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - ">="
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: '0'
|
|
21
|
+
type: :runtime
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: '0'
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: json
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - ">="
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '0'
|
|
35
|
+
type: :runtime
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '0'
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: bundler
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - "~>"
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '1.14'
|
|
49
|
+
type: :development
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - "~>"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '1.14'
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: rake
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - "~>"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '10.0'
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - "~>"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '10.0'
|
|
70
|
+
description: Advanced docker and consul control scripts
|
|
71
|
+
email:
|
|
72
|
+
- igodko@rnds.pro
|
|
73
|
+
- kinnalru@gmail.com
|
|
74
|
+
executables:
|
|
75
|
+
- consul.rb
|
|
76
|
+
- merger.rb
|
|
77
|
+
- waiter.rb
|
|
78
|
+
extensions: []
|
|
79
|
+
extra_rdoc_files: []
|
|
80
|
+
files:
|
|
81
|
+
- ".dockerignore"
|
|
82
|
+
- ".gitignore"
|
|
83
|
+
- ".rspec"
|
|
84
|
+
- ".rubocop.yml"
|
|
85
|
+
- ".travis.yml"
|
|
86
|
+
- Gemfile
|
|
87
|
+
- Gemfile.lock
|
|
88
|
+
- README.md
|
|
89
|
+
- bin/consul.rb
|
|
90
|
+
- bin/merger.rb
|
|
91
|
+
- bin/waiter.rb
|
|
92
|
+
- docker/Dockerfile
|
|
93
|
+
- docker/docker-compose.yml
|
|
94
|
+
- docker/down.sh
|
|
95
|
+
- docker/run_tests.sh
|
|
96
|
+
- docker_toolkit.gemspec
|
|
97
|
+
- lib/docker_toolkit.rb
|
|
98
|
+
- lib/docker_toolkit/version.rb
|
|
99
|
+
homepage: https://github.com/RnD-Soft/docker_toolkit
|
|
100
|
+
licenses: []
|
|
101
|
+
metadata: {}
|
|
102
|
+
post_install_message:
|
|
103
|
+
rdoc_options: []
|
|
104
|
+
require_paths:
|
|
105
|
+
- lib
|
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 2.1.0
|
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - ">="
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '0'
|
|
116
|
+
requirements: []
|
|
117
|
+
rubyforge_project:
|
|
118
|
+
rubygems_version: 2.7.3
|
|
119
|
+
signing_key:
|
|
120
|
+
specification_version: 4
|
|
121
|
+
summary: Helper scripts for work with docker and consul
|
|
122
|
+
test_files: []
|