pygmy-traefik 0.9.10

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 912636babd6e8183bc92c9030ca4a5d8b669e53b
4
+ data.tar.gz: 2911b44d98e787055cd03f22fd85a214a4b51f48
5
+ SHA512:
6
+ metadata.gz: 339d451345b29a038989c932fc4ce99bcaf4924f4907f096de87d5053358f0bf3df3f753f7b11bc2ae0594952ec545ca84fa0f94a65c6dcd7f9791eddb2b9bce
7
+ data.tar.gz: e910eb818a6dc1e303f5836a0fc8432517955b8d161a8ed598b00db2dbf484da86838aeb7d1d53d610764864b0d4187c19f1bc59c97add9779d180c5912bea05
@@ -0,0 +1,371 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+ require 'yaml'
5
+
6
+ require 'pygmy'
7
+
8
+ class PygmyBin < Thor
9
+ class_option :verbose, type: :boolean, aliases: '-v', default: false
10
+
11
+ desc 'up', 'Bring up pygmy services (dnsmasq, haproxy, mailhog, resolv, ssh-agent)'
12
+ long_desc <<-LONGDESC
13
+ Bring up pygmy services (dnsmasq, haproxy, resolv, ssh-agent)
14
+
15
+ When run, there will be two docker containers started:
16
+
17
+ - dnsmasq: to resolve DNS requests for your the domain *.docker.amazee.io (unless you add --no-resolver)
18
+
19
+ - haproxy: to forward HTTP and HTTPs requests to the docker containers running Drupal.
20
+
21
+ - traefik: optional alternative to haproxy. (add --traefik to enable)
22
+
23
+ - ssh-agent: to keep the ssh-agent at one single place, so that all other docker containers
24
+ can consume the ssh key. You can bypass automatically adding keys to the agent by using --no-addkey.
25
+
26
+ On Linux: The local resolver (/etc/resolv.conf) will be configured to use the dnsmasq
27
+ instance as a nameserver. (unless you add --no-resolver)
28
+
29
+ On Mac: A resolver file (/etc/resolver/docker.amazee.io) will be created to use the dnsmasq
30
+ instance as a nameserver for all *.docker.amazee.io domains. (unless you add --no-resolver)
31
+
32
+ > $ pygmy up
33
+ LONGDESC
34
+ option :addkey, type: :boolean, default:true
35
+ option :resolver, type: :boolean, default: true
36
+ option :traefik, type: :boolean, default: false
37
+ def up
38
+ exec_up(options)
39
+ end
40
+
41
+ desc 'update', 'Pulls Docker Images and recreates the Containers'
42
+ long_desc <<-LONGDESC
43
+ Runs 'docker pull' on the Docker images in order to get their newest versions.
44
+ After that restarts all containers with removing them, so that the new images are used.
45
+ LONGDESC
46
+ option :resolver, type: :boolean, default: true
47
+ option :traefik, type: :boolean, default: false
48
+ def update
49
+ exec_update
50
+ end
51
+
52
+ desc 'stop', 'Stop all pygmy services'
53
+ long_desc <<-LONGDESC
54
+ Stops all pygmy services. Can optionally pass [-d|--destroy]
55
+ to destroy the containers when they stop.
56
+
57
+ > $ pygmy stop [-d|--destroy]
58
+ LONGDESC
59
+ option :destroy, type: :boolean, aliases: '-d', default: false
60
+ def stop
61
+ exec_stop(options)
62
+ end
63
+
64
+ desc 'down', 'Stop and destroy all pygmy services'
65
+ long_desc <<-LONGDESC
66
+ Stops all pygmy services and destroy the containers when they stop.
67
+
68
+ > $ pygmy down
69
+ LONGDESC
70
+ def down
71
+ exec_stop({:destroy => true})
72
+ end
73
+
74
+ desc 'addkey [~/.ssh/id_rsa]', 'Add additional ssh-key'
75
+ long_desc <<-LONGDESC
76
+ Adds an additional ssh key to the ssh-agent.
77
+ Needs the absolute path to key as an argument
78
+ or uses ~/.ssh/id_rsa if none provided
79
+
80
+ > $ pygmy addkey [~/.ssh/other_key]
81
+ LONGDESC
82
+ def addkey(key = "#{Dir.home}/.ssh/id_rsa")
83
+ add_ssh_key(key)
84
+ end
85
+
86
+ desc 'version', 'Check current installed version of pygmy'
87
+ def version
88
+ puts "Pygmy - Version: #{Pygmy::VERSION}"
89
+ end
90
+
91
+ desc 'restart', 'Stop and restart all pygmy services'
92
+ long_desc <<-LONGDESC
93
+ Stop and restart pygmy services (dnsmasq, resolv, haproxy, mailhog, ssh-agent)
94
+
95
+ > $ pygmy restart [-d|--destroy]
96
+ LONGDESC
97
+ option :destroy, type: :boolean, aliases: '-d', default: false
98
+ option :resolver, type: :boolean, default: true
99
+ option :traefik, type: :boolean, default: false
100
+ def restart
101
+ exec_stop(options)
102
+ exec_up(options)
103
+ end
104
+
105
+ desc 'status', 'Report status of the pygmy services'
106
+ long_desc <<-LONGDESC
107
+ Checks the current status of the services managed by pygmy.
108
+ This includes dnsmasq, mailhog, and resolv
109
+
110
+ > $ pygmy status
111
+ LONGDESC
112
+ def status
113
+ exec_status(options)
114
+ end
115
+
116
+ private
117
+
118
+ def exec_update
119
+ Pygmy::Haproxy.pull
120
+ Pygmy::Mailhog.pull
121
+ Pygmy::SshAgent.pull
122
+ Pygmy::Traefik.pull
123
+ Pygmy::Amazee.pull_all
124
+ puts "Done. Recreating containers...".yellow
125
+ exec_stop({:destroy => true})
126
+ exec_up({})
127
+ end
128
+
129
+ def exec_up(options)
130
+
131
+ if options[:resolver]
132
+ if Pygmy::Dnsmasq.start
133
+ puts "Successfully started dnsmasq".green
134
+ else
135
+ puts "Error starting dnsmasq".red
136
+ end
137
+ end
138
+
139
+ unless options[:traefik]
140
+ if Pygmy::Traefik.running?
141
+ puts "[*] Traefik: Running as docker container #{Pygmy::Traefik.container_name}".red
142
+ elsif Pygmy::Haproxy.start
143
+ puts "Successfully started haproxy".green
144
+ else
145
+ puts "Error starting haproxy".red
146
+ end
147
+ end
148
+
149
+ if options[:traefik]
150
+ if Pygmy::Haproxy.running?
151
+ puts "[*] Haproxy: Running as docker container #{Pygmy::Haproxy.container_name}".red
152
+ elsif Pygmy::Traefik.start
153
+ puts "Successfully started traefik".green
154
+ else
155
+ puts "Error starting traefik".red
156
+ end
157
+ end
158
+
159
+ if Pygmy::DockerNetwork.create
160
+ puts "Successfully created amazeeio network".green
161
+ else
162
+ puts "Error creating amazeeio network".red
163
+ end
164
+
165
+ unless options[:traefik]
166
+ if Pygmy::Haproxy.running?
167
+ if Pygmy::DockerNetwork.connect
168
+ puts "Successfully connected haproxy to amazeeio network".green
169
+ else
170
+ puts "Error connecting haproxy to amazeeio network".red
171
+ end
172
+ end
173
+ end
174
+
175
+ if options[:traefik]
176
+ unless Pygmy::Haproxy.running?
177
+ if Pygmy::Traefik.connect
178
+ puts "Successfully connected traefik to amazeeio network".green
179
+ else
180
+ puts "Error connecting traefik to amazeeio network".red
181
+ end
182
+ end
183
+ end
184
+
185
+ if Pygmy::Mailhog.start
186
+ puts "Successfully started mailhog".green
187
+ else
188
+ puts "Error starting mailhog".red
189
+ end
190
+
191
+ if Pygmy::SshAgent.start
192
+ puts "Successfully started ssh-agent".green
193
+ else
194
+ puts "Error starting ssh-agent".red
195
+ end
196
+
197
+ if options[:resolver]
198
+ if Pygmy::Resolv.configure
199
+ puts "Successfully configured local resolver".green
200
+ else
201
+ puts "Error configuring local resolver".red
202
+ end
203
+ end
204
+
205
+ if options[:addkey]
206
+ if Pygmy::SshAgentAddKey.add_ssh_key
207
+ puts "Successfully injected ssh key".green
208
+ else
209
+ puts "Error injected ssh key".red
210
+ end
211
+ end
212
+ end
213
+
214
+ def exec_status(_options)
215
+
216
+ if Pygmy::Dnsmasq.running?
217
+ puts "[*] Dnsmasq: Running as docker container #{Pygmy::Dnsmasq.container_name}".green
218
+ else
219
+ puts "[*] Dnsmasq is not running".red
220
+ end
221
+
222
+ if Pygmy::Haproxy.running?
223
+ puts "[*] Haproxy: Running as docker container #{Pygmy::Haproxy.container_name}".green
224
+ else
225
+ puts "[*] Haproxy is not running".red
226
+ end
227
+
228
+ if Pygmy::DockerNetwork.exists?
229
+ puts "[*] Network: Exists as name #{Pygmy::DockerNetwork.network_name}".green
230
+ else
231
+ puts "[*] Network does not exist".red
232
+ end
233
+
234
+ if Pygmy::DockerNetwork.haproxy_connected?
235
+ puts "[*] Network: Haproxy #{Pygmy::DockerNetwork.haproxy_name} connected to #{Pygmy::DockerNetwork.network_name}".green
236
+ else
237
+ puts "[*] Haproxy is not connected to #{Pygmy::DockerNetwork.network_name}".red
238
+ end
239
+
240
+ if Pygmy::Traefik.running?
241
+ puts "[*] Traefik: Running as docker container #{Pygmy::Traefik.container_name}".green
242
+ else
243
+ puts "[*] Traefik is not running".red
244
+ end
245
+
246
+ if Pygmy::Traefik.connected?
247
+ puts "[*] Network: Traefik #{Pygmy::Traefik.container_name} connected to #{Pygmy::DockerNetwork.network_name}".green
248
+ else
249
+ puts "[*] Traefik is not connected to #{Pygmy::DockerNetwork.network_name}".red
250
+ end
251
+
252
+ if Pygmy::Mailhog.running?
253
+ puts "[*] Mailhog: Running as docker container #{Pygmy::Mailhog.container_name}".green
254
+ else
255
+ puts "[*] Mailhog is not running".red
256
+ end
257
+
258
+ if Pygmy::Resolv.has_our_nameserver?
259
+ puts "[*] Resolv is properly configured".green
260
+ else
261
+ puts "[*] Resolv is not configured".red
262
+ end
263
+
264
+ if Pygmy::SshAgent.running?
265
+ puts "[*] ssh-agent: Running as docker container #{Pygmy::SshAgent.container_name}, loaded keys:".green
266
+ Pygmy::SshAgentAddKey.show_ssh_keys
267
+ else
268
+ puts "[*] ssh-agent is not running".red
269
+ end
270
+
271
+ end
272
+
273
+
274
+ def add_ssh_key(key)
275
+
276
+ if Pygmy::SshAgent.running?
277
+ if Pygmy::SshAgentAddKey.add_ssh_key(key)
278
+ puts "Successfully added ssh key".green
279
+ else
280
+ puts "Error added ssh key".red
281
+ end
282
+ else
283
+ puts "ssh-agent is not running, cannot add key".red
284
+ end
285
+
286
+ end
287
+
288
+ def exec_stop(options)
289
+ if Pygmy::Resolv.clean
290
+ puts "Resolver removed".green
291
+ else
292
+ puts "Error while removing the resolver".red
293
+ end
294
+
295
+ if Pygmy::Dnsmasq.stop
296
+ puts "Dnsmasq container stopped".green
297
+ if options[:destroy]
298
+ if Pygmy::Dnsmasq.delete
299
+ puts "Dnsmasq container successfully deleted".green
300
+ else
301
+ puts "Dnsmasq container failed to delete".red
302
+ end
303
+ end
304
+ else
305
+ puts "Dnsmasq container failed to stop".red
306
+ end
307
+
308
+ if Pygmy::Mailhog.stop
309
+ puts "Mailhog container stopped".green
310
+ if options[:destroy]
311
+ if Pygmy::Mailhog.delete
312
+ puts "Mailhog container successfully deleted".green
313
+ else
314
+ puts "Mailhog container failed to delete".red
315
+ end
316
+ end
317
+ else
318
+ puts "Mailhog container failed to stop".red
319
+ end
320
+
321
+ if Pygmy::SshAgent.stop
322
+ puts "ssh-agent container stopped".green
323
+ if options[:destroy]
324
+ if Pygmy::SshAgent.delete
325
+ puts "ssh-agent container successfully deleted".green
326
+ else
327
+ puts "ssh-agent container failed to delete".red
328
+ end
329
+ end
330
+ else
331
+ puts "ssh-agent container failed to stop".red
332
+ end
333
+
334
+ if Pygmy::Haproxy.stop
335
+ puts "Haproxy container stopped".green
336
+ if options[:destroy]
337
+ if Pygmy::Haproxy.delete
338
+ puts "Haproxy container successfully deleted".green
339
+ else
340
+ puts "Haproxy container failed to delete".red
341
+ end
342
+ end
343
+ else
344
+ puts "Haproxy container failed to stop".red
345
+ end
346
+
347
+ if Pygmy::Traefik.stop
348
+ puts "Traefik container stopped".green
349
+ if options[:destroy]
350
+ if Pygmy::Traefik.delete
351
+ puts "Traefik container successfully deleted".green
352
+ else
353
+ puts "Traefik container failed to delete".red
354
+ end
355
+ end
356
+ else
357
+ puts "Traefik container failed to stop".red
358
+ end
359
+
360
+ end
361
+ end
362
+
363
+ aliases = {
364
+ 'start' => 'up',
365
+ }
366
+
367
+ if !ARGV.empty? && %w[-v --version].include?(ARGV.first)
368
+ puts "Pygmy - Version: #{Pygmy::VERSION}"
369
+ else
370
+ PygmyBin.start(ARGV.map { |a| aliases.keys.include?(a) ? aliases[a] : a })
371
+ end
@@ -0,0 +1,3 @@
1
+ Gem.find_files('pygmy/**/*.rb').each do |path|
2
+ require path.gsub(/\.rb$/, '') unless path =~ /bot.*cli/
3
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class Amazee
5
+ extend Pygmy::DockerService
6
+
7
+ def self.pull(image_name)
8
+ puts "Pulling Docker Image #{Shellwords.escape(image_name)}".yellow
9
+ pull_cmd = "docker pull #{Shellwords.escape(image_name)}"
10
+ success = Sh.run_command(pull_cmd).success?
11
+ unless success
12
+ raise RuntimeError.new(
13
+ "Failed to update #{self.container_name}. Command #{pull_cmd} failed"
14
+ )
15
+ end
16
+ end
17
+
18
+ def self.ls_cmd
19
+ cmd = 'docker image ls --format "{{.Repository}}:{{.Tag}}"'
20
+ list = Sh.run_command(cmd)
21
+
22
+ # For better handling of containers, we should compare our
23
+ # results against a whitelist instead of preferential
24
+ # treatment of linux pipes.
25
+ containers = list.stdout.split("\n")
26
+ amazee_containers = []
27
+ containers.each do |container|
28
+ # Selectively target amazeeio/* images.
29
+ if container.include?('amazeeio/')
30
+ # Filter out items which we don't want.
31
+ unless container.include?("none") || container.include?("ssh-agent") || container.include?("haproxy")
32
+ amazee_containers.push(container)
33
+ end
34
+ end
35
+ end
36
+ amazee_containers
37
+ end
38
+
39
+ def self.pull_all
40
+ list = self.ls_cmd
41
+ unless list.nil?
42
+ list.each do |image|
43
+ pull(image)
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class Dnsmasq
5
+ extend Pygmy::DockerService
6
+
7
+ def self.image_name
8
+ 'andyshinn/dnsmasq:2.75'
9
+ end
10
+
11
+ def self.container_name
12
+ 'amazeeio-dnsmasq'
13
+ end
14
+
15
+ def self.domain
16
+ 'docker.amazee.io'
17
+ end
18
+
19
+ def self.addr
20
+ '127.0.0.1'
21
+ end
22
+
23
+ def self.run_cmd(domain = self.domain, addr = self.addr)
24
+ "docker run -d -p 53:53/tcp -p 53:53/udp --name=#{Shellwords.escape(self.container_name)} " \
25
+ "--cap-add=NET_ADMIN #{Shellwords.escape(self.image_name)} -A /#{Shellwords.escape(domain)}/#{Shellwords.escape(addr)}"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,74 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class DockerNetwork
5
+ extend Pygmy::DockerService
6
+
7
+ def self.network_name
8
+ 'amazeeio-network'
9
+ end
10
+
11
+ def self.haproxy_name
12
+ 'amazeeio-haproxy'
13
+ end
14
+
15
+ def self.create_cmd
16
+ "docker network create #{self.network_name}"
17
+ end
18
+
19
+ def self.connect_haproxy_cmd
20
+ "docker network connect #{self.network_name} #{self.haproxy_name}"
21
+ end
22
+
23
+ def self.create
24
+ unless self.exists?
25
+ unless Sh.run_command(self.create_cmd).success?
26
+ raise RuntimeError.new(
27
+ "Failed to create #{self.network_name}. Command #{self.create_cmd} failed"
28
+ )
29
+ end
30
+ end
31
+ self.exists?
32
+ end
33
+
34
+ def self.connect
35
+ unless self.haproxy_connected?
36
+ unless Sh.run_command(self.connect_haproxy_cmd).success?
37
+ raise RuntimeError.new(
38
+ "Failed to connect #{self.haproxy_name} to #{self.network_name}. Command #{self.connect_haproxy_cmd} failed"
39
+ )
40
+ end
41
+ end
42
+ self.haproxy_connected?
43
+ end
44
+
45
+ def self.haproxy_connected?(network_name = self.network_name, haproxy_name = self.haproxy_name)
46
+ !!(self.inspect_containers(network_name) =~ /#{haproxy_name}/)
47
+ end
48
+
49
+ def self.exists?(network_name = self.network_name)
50
+ !!(self.ls =~ /#{network_name}/)
51
+ end
52
+
53
+ def self.inspect_containers(network_name = self.network_name)
54
+ cmd = "docker network inspect #{self.network_name} -f '{{.Containers}}'"
55
+ ret = Sh.run_command(cmd)
56
+ if ret.success?
57
+ return ret.stdout
58
+ else
59
+ raise RuntimeError.new("Failure running command '#{cmd}'")
60
+ end
61
+ end
62
+
63
+ def self.ls
64
+ cmd = "docker network ls"
65
+ ret = Sh.run_command(cmd)
66
+ if ret.success?
67
+ return ret.stdout
68
+ else
69
+ raise RuntimeError.new("Failure running command '#{cmd}'")
70
+ end
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,70 @@
1
+ require 'shellwords'
2
+
3
+ module Pygmy
4
+ module DockerService
5
+ def start
6
+ unless self.running?
7
+ success = if self.container_exists?
8
+ Sh.run_command(self.start_cmd).success?
9
+ else
10
+ Sh.run_command(self.run_cmd).success?
11
+ end
12
+ unless success
13
+ raise RuntimeError.new(
14
+ "Failed to run #{self.container_name}. Command #{self.run_cmd} failed"
15
+ )
16
+ end
17
+ end
18
+ self.running?
19
+ end
20
+
21
+ def pull
22
+ puts "Pulling Docker Image #{Shellwords.escape(self.image_name)}".yellow
23
+ success = Sh.run_command("docker pull #{Shellwords.escape(self.image_name)}").success?
24
+ unless success
25
+ raise RuntimeError.new(
26
+ "Failed to update #{self.container_name}. Command #{self.pull_cmd} failed"
27
+ )
28
+ end
29
+ end
30
+
31
+ def running?(container_name = self.container_name)
32
+ !!(self.ps =~ /#{container_name}/)
33
+ end
34
+
35
+ def container_exists?(container_name = self.container_name)
36
+ !!(self.ps(true) =~ /#{container_name}/)
37
+ end
38
+
39
+ def ps(all = false)
40
+ cmd = "docker ps#{all ? ' -a' : ''}"
41
+ ret = Sh.run_command(cmd)
42
+ if ret.success?
43
+ return ret.stdout
44
+ else
45
+ raise RuntimeError.new("Failure running command '#{cmd}'")
46
+ end
47
+ end
48
+
49
+ def has_docker_client?
50
+ Sh.run_command('which docker').success?
51
+ end
52
+
53
+ def stop(container_name = self.container_name)
54
+ Sh.run_command("docker stop -t 1 #{Shellwords.escape(container_name)}") if self.running?
55
+ !self.running?
56
+ end
57
+
58
+ def delete(container_name = self.container_name)
59
+ if self.container_exists?
60
+ self.stop if self.running?
61
+ Sh.run_command("docker rm #{Shellwords.escape(container_name)}")
62
+ end
63
+ !self.container_exists?
64
+ end
65
+
66
+ def start_cmd
67
+ "docker start #{Shellwords.escape(self.container_name)}"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class Haproxy
5
+ extend Pygmy::DockerService
6
+
7
+ def self.image_name
8
+ 'amazeeio/haproxy'
9
+ end
10
+
11
+ def self.container_name
12
+ 'amazeeio-haproxy'
13
+ end
14
+
15
+ def self.run_cmd
16
+ "docker run -d " \
17
+ "-p 80:80 -p 443:443 " \
18
+ "--volume=/var/run/docker.sock:/tmp/docker.sock " \
19
+ "--restart=always " \
20
+ "--name=#{Shellwords.escape(self.container_name)} " \
21
+ "#{Shellwords.escape(self.image_name)}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ module Pygmy
2
+ module Linux
3
+ def self.bash(command)
4
+ system("bash -c '#{command}'")
5
+ end
6
+
7
+ def self.ubuntu?
8
+ self.bash(self.ubuntu_cmd)
9
+ end
10
+
11
+ def self.fedora?
12
+ self.bash(self.fedora_cmd)
13
+ end
14
+
15
+ def self.arch?
16
+ self.bash(self.arch_cmd)
17
+ end
18
+
19
+ def self.osx?
20
+ self.bash('uname -a | grep "Darwin" > /dev/null')
21
+ end
22
+
23
+ def self.ubuntu_cmd
24
+ %q(
25
+ if $(which lsb_release >/dev/null 2>&1); then
26
+ lsb_release -d | grep --color=auto "Ubuntu" > /dev/null
27
+ else
28
+ uname -a | grep --color=auto "Ubuntu" > /dev/null
29
+ fi
30
+ )
31
+ end
32
+
33
+ def self.fedora_cmd
34
+ %q(
35
+ if $(which lsb_release >/dev/null 2>&1); then
36
+ lsb_release -d | grep --color=auto "Fedora" > /dev/null
37
+ else
38
+ uname -r | grep --color=auto "fc" > /dev/null
39
+ fi
40
+ )
41
+ end
42
+
43
+ def self.arch_cmd
44
+ %q(
45
+ if $(which lsb_release >/dev/null 2>&1); then
46
+ lsb_release -d | grep --color=auto "Arch" > /dev/null
47
+ else
48
+ uname -a | grep --color=auto "ARCH" > /dev/null
49
+ fi
50
+ )
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class Mailhog
5
+ extend Pygmy::DockerService
6
+
7
+ def self.image_name
8
+ 'mailhog/mailhog'
9
+ end
10
+
11
+ def self.container_name
12
+ 'mailhog.docker.amazee.io'
13
+ end
14
+
15
+ def self.domain
16
+ 'docker.amazee.io'
17
+ end
18
+
19
+ def self.addr
20
+ '127.0.0.1'
21
+ end
22
+
23
+ def self.run_cmd(domain = self.domain, addr = self.addr)
24
+ "docker run --restart=always -d -p 1025:1025 --expose 80 -u 0 --name=#{Shellwords.escape(self.container_name)} " \
25
+ '-e "MH_UI_BIND_ADDR=0.0.0.0:80" ' \
26
+ '-e "MH_API_BIND_ADDR=0.0.0.0:80" ' \
27
+ '-e "AMAZEEIO=AMAZEEIO" ' \
28
+ "--label traefik.frontend.rule=Host:#{Shellwords.escape(self.container_name)} " \
29
+ "#{Shellwords.escape(self.image_name)}"
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,99 @@
1
+ require 'colorize'
2
+ require 'tempfile'
3
+ require 'pathname'
4
+
5
+ module Pygmy
6
+ module Resolv
7
+ def self.common_resolv_file
8
+ '/etc/resolv.conf'
9
+ end
10
+
11
+ def self.ubuntu_resolv_file
12
+ #'/etc/resolvconf/resolv.conf.d/base'
13
+ # For now, use the common_resolv_file
14
+ self.common_resolv_file
15
+ end
16
+
17
+ def self.file_comment
18
+ '# added by amazee.io pygmy'
19
+ end
20
+
21
+ def self.nameserver
22
+ "127.0.0.1"
23
+ end
24
+
25
+ def self.file_nameserver_line
26
+ "nameserver #{self.nameserver}"
27
+ end
28
+
29
+ def self.nameserver_contents
30
+ "#{self.file_nameserver_line} #{self.file_comment}"
31
+ end
32
+
33
+ def self.resolv_file
34
+ if Linux.ubuntu?
35
+ return self.ubuntu_resolv_file
36
+ elsif Linux.fedora? || Linux.arch? || File.exist?(self.common_resolv_file)
37
+ return self.common_resolv_file
38
+ else
39
+ raise RuntimeError.new(
40
+ "Unable to determine location of resolv file"
41
+ )
42
+ end
43
+ end
44
+
45
+
46
+ def self.configure
47
+ if Linux.osx?
48
+ return ResolvOsx.create_resolver?
49
+ end
50
+ # we want to be the first nameserver in the list for performance reasons
51
+ # we only want to add the nameserver if it isn't already there
52
+ prev_conts = self.resolv_file_contents
53
+ unless self.contents_has_our_nameserver?(prev_conts)
54
+ if prev_conts =~ /nameserver/
55
+ prev_conts.sub!(/nameserver/, "#{self.nameserver_contents}\nnameserver")
56
+ else
57
+ prev_conts = "#{prev_conts}\n#{self.nameserver_contents}"
58
+ end
59
+ prev_conts.gsub!(/\s+$/, '')
60
+ self.write_to_file(prev_conts)
61
+ end
62
+ self.has_our_nameserver?
63
+ end
64
+
65
+ def self.clean
66
+ if Linux.osx?
67
+ return ResolvOsx.clean?
68
+ end
69
+ prev_conts = self.resolv_file_contents
70
+ if self.contents_has_our_nameserver?(prev_conts)
71
+ prev_conts.gsub!(/#{Regexp.escape(self.nameserver_contents + "\n")}/, '')
72
+ prev_conts.gsub!(/\s+$/, '')
73
+ self.write_to_file(prev_conts)
74
+ end
75
+ !self.has_our_nameserver?
76
+ end
77
+
78
+ def self.write_to_file(contents)
79
+ # have to use this hack cuz we don't run as root :-(
80
+ puts "Requesting sudo to write to #{self.resolv_file}".green
81
+ Bash.run_command("echo -e '#{contents}' | sudo tee #{Shellwords.escape(self.resolv_file)} >/dev/null")
82
+ end
83
+
84
+ def self.resolv_file_contents
85
+ File.read(self.resolv_file)
86
+ end
87
+
88
+ def self.has_our_nameserver?
89
+ if Linux.osx?
90
+ return ResolvOsx.resolver_file_exists?
91
+ end
92
+ self.contents_has_our_nameserver?(self.resolv_file_contents)
93
+ end
94
+
95
+ def self.contents_has_our_nameserver?(contents)
96
+ !!((contents =~ /#{self.file_comment}/) || (contents =~ /#{self.file_nameserver_line}/))
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,60 @@
1
+ require 'colorize'
2
+ require 'tempfile'
3
+ require 'pathname'
4
+
5
+ module Pygmy
6
+ module ResolvOsx
7
+ def self.resolver_dir
8
+ Pathname("/etc/resolver")
9
+ end
10
+
11
+ def self.resolver_file
12
+ "/etc/resolver/docker.amazee.io"
13
+ end
14
+
15
+ def self.create_resolver?
16
+ puts "setting up DNS resolution and loopback alias IP, this may require sudo".green
17
+ unless self.resolver_dir.directory?
18
+ self.system!("creating #{self.resolver_dir}", "sudo", "mkdir", "-p", self.resolver_dir)
19
+ end
20
+ Tempfile.open('amazeeio_pygmy-dnsmasq') do |f|
21
+ f.write(self.resolver_contents)
22
+ f.close
23
+ self.system!("creating #{self.resolver_file}", "sudo", "cp", f.path, self.resolver_file)
24
+ self.system!("creating #{self.resolver_file}", "sudo", "chmod", "644", self.resolver_file)
25
+ end
26
+ self.system!("creating loopback IP alias 172.16.172.16", "sudo", "ifconfig", "lo0", "alias", "172.16.172.16")
27
+ self.system!("restarting mDNSResponder", "sudo", "killall", "mDNSResponder")
28
+ end
29
+
30
+ def self.clean?
31
+ puts "Removing resolver file and loopback alias IP, this may require sudo".green
32
+ begin
33
+ self.system!("removing resolverfile", "sudo", "rm", "-f", self.resolver_file)
34
+ self.system!("removing loopback IP alias 172.16.172.16", "sudo", "ifconfig", "lo0", "-alias", "172.16.172.16")
35
+ system!("restarting mDNSResponder", "sudo", "killall", "mDNSResponder")
36
+ rescue Exception => e
37
+ puts e.message
38
+ end
39
+ end
40
+
41
+ def self.system!(step, *args)
42
+ system(*args.map(&:to_s)) || raise("Error with the #{name} daemon during #{step}")
43
+ end
44
+
45
+ def self.resolver_contents; <<-EOS.gsub(/^ /, '')
46
+ # Generated by amazeeio pygmy
47
+ nameserver 127.0.0.1
48
+ port 53
49
+ EOS
50
+ end
51
+
52
+ def self.resolver_file_contents
53
+ File.read(self.resolver_file) unless !File.file?(self.resolver_file)
54
+ end
55
+
56
+ def self.resolver_file_exists?
57
+ (self.resolver_file_contents == self.resolver_contents)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,25 @@
1
+ require 'ostruct'
2
+
3
+ module Pygmy
4
+ module Sh
5
+ def self.run_command(command)
6
+ stdout = `#{command}`
7
+ OpenStruct.new({
8
+ success?: $?.exitstatus == 0,
9
+ exitstatus: $?.exitstatus,
10
+ stdout: stdout
11
+ })
12
+ end
13
+ end
14
+
15
+ module Bash
16
+ def self.run_command(command)
17
+ stdout = `bash -c "#{command}"`
18
+ OpenStruct.new({
19
+ success?: $?.exitstatus == 0,
20
+ exitstatus: $?.exitstatus,
21
+ stdout: stdout
22
+ })
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class SshAgent
5
+ extend Pygmy::DockerService
6
+
7
+ def self.image_name
8
+ 'amazeeio/ssh-agent'
9
+ end
10
+
11
+ def self.container_name
12
+ 'amazeeio-ssh-agent'
13
+ end
14
+
15
+ def self.run_cmd
16
+ "docker run -d " \
17
+ "--restart=always " \
18
+ "--name=#{Shellwords.escape(self.container_name)} " \
19
+ "#{Shellwords.escape(self.image_name)}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ module Pygmy
2
+ class SshAgentAddKey
3
+ def self.image_name
4
+ 'amazeeio/ssh-agent'
5
+ end
6
+
7
+ def self.container_name
8
+ 'amazeeio-ssh-agent-add-key'
9
+ end
10
+
11
+ def self.add_ssh_key(key = "#{Dir.home}/.ssh/id_rsa")
12
+ if File.file?(key)
13
+ system("docker run --rm -it " \
14
+ "--volume=#{key}:/#{key} " \
15
+ "--volumes-from=amazeeio-ssh-agent " \
16
+ "--name=#{Shellwords.escape(self.container_name)} " \
17
+ "#{Shellwords.escape(self.image_name)} " \
18
+ "ssh-add #{key}")
19
+ else
20
+ puts "ssh key: #{key}, does not exist, ignoring...".yellow
21
+ return false
22
+ end
23
+ end
24
+
25
+ def self.show_ssh_keys
26
+ system("docker run --rm -it " \
27
+ "--volumes-from=amazeeio-ssh-agent " \
28
+ "--name=#{Shellwords.escape(self.container_name)} " \
29
+ "#{Shellwords.escape(self.image_name)} " \
30
+ "ssh-add -l")
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,52 @@
1
+ require_relative 'docker_service'
2
+
3
+ module Pygmy
4
+ class Traefik
5
+ extend Pygmy::DockerService
6
+
7
+ def self.image_name
8
+ 'containous/traefik'
9
+ end
10
+
11
+ def self.container_name
12
+ 'traefik.docker.amazee.io'
13
+ end
14
+
15
+ def self.network_name
16
+ 'amazeeio-network'
17
+ end
18
+
19
+ def self.connect_cmd
20
+ "docker network connect #{self.network_name} #{self.container_name}"
21
+ end
22
+
23
+ def self.connected?
24
+ !!(Pygmy::DockerNetwork.inspect_containers(self.network_name) =~ /#{self.container_name}/)
25
+ end
26
+
27
+ def self.connect
28
+ unless self.connected?
29
+ unless Sh.run_command(self.connect_cmd).success?
30
+ raise RuntimeError.new(
31
+ "Failed to connect #{self.container_name} to #{self.network_name}. Command #{self.connect_cmd} failed"
32
+ )
33
+ end
34
+ end
35
+ self.connected?
36
+ end
37
+
38
+ def self.run_cmd
39
+ "docker run -d " \
40
+ "-p 80:80 -p 8080:8080 -p 443:443 " \
41
+ "--restart always " \
42
+ "--volume=/var/run/docker.sock:/var/run/docker.sock " \
43
+ "--name=#{Shellwords.escape(self.container_name)} " \
44
+ "--label traefik.frontend.rule=Host:#{Shellwords.escape(self.container_name)} " \
45
+ "#{Shellwords.escape(self.image_name)} " \
46
+ "--api --docker " \
47
+ '--docker.network=amazeeio-network ' \
48
+ "--docker.domain=docker.amazee.io"
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,4 @@
1
+ module Pygmy
2
+ VERSION = '0.9.10'
3
+ DATE = '2018-11-19'
4
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pygmy-traefik
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.10
5
+ platform: ruby
6
+ authors:
7
+ - Michael Schmid
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.19'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.19'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ptools
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '8.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '8.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: codeclimate-test-reporter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.5'
111
+ description: To fully and easy run a local Drupal development system you need more
112
+ then just a docker container with the Drupal running. Default development workflows
113
+ involves running multiple sites at the same time, interacting with other services
114
+ which are authenticated via ssh and more.Pygmy makes usre that the required Docker
115
+ containers are started and that youcomfortably can access the Drupal Containers
116
+ just via the browser.
117
+ email: michael@amazee.io
118
+ executables:
119
+ - pygmy
120
+ extensions: []
121
+ extra_rdoc_files: []
122
+ files:
123
+ - bin/pygmy
124
+ - lib/pygmy.rb
125
+ - lib/pygmy/amazee.rb
126
+ - lib/pygmy/dnsmasq.rb
127
+ - lib/pygmy/docker_network.rb
128
+ - lib/pygmy/docker_service.rb
129
+ - lib/pygmy/haproxy.rb
130
+ - lib/pygmy/linux.rb
131
+ - lib/pygmy/mailhog.rb
132
+ - lib/pygmy/resolv.rb
133
+ - lib/pygmy/resolv_osx.rb
134
+ - lib/pygmy/shell.rb
135
+ - lib/pygmy/ssh_agent.rb
136
+ - lib/pygmy/ssh_agent_add_key.rb
137
+ - lib/pygmy/traefik.rb
138
+ - lib/pygmy/version.rb
139
+ homepage: https://github.com/amazeeio/pygmy
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.5.2.3
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: pygmy provides the required servies to run the amazee.io Drupal local development
163
+ environment on linux.
164
+ test_files: []