pygmy-apple 0.9.12.pre.rc1
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/bin/pygmy-apple +310 -0
- data/lib/pygmy.rb +3 -0
- data/lib/pygmy/amazee.rb +62 -0
- data/lib/pygmy/dnsmasq.rb +28 -0
- data/lib/pygmy/docker_network.rb +74 -0
- data/lib/pygmy/docker_service.rb +70 -0
- data/lib/pygmy/haproxy.rb +24 -0
- data/lib/pygmy/linux.rb +53 -0
- data/lib/pygmy/mailhog.rb +32 -0
- data/lib/pygmy/resolv.rb +99 -0
- data/lib/pygmy/resolv_osx.rb +60 -0
- data/lib/pygmy/shell.rb +25 -0
- data/lib/pygmy/ssh_agent.rb +22 -0
- data/lib/pygmy/ssh_agent_add_key.rb +34 -0
- data/lib/pygmy/version.rb +4 -0
- metadata +162 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9dc0ecdb1178d91ae7430211011520aaa0ca7633a25ccc6b17f023b885e5fa8a
|
|
4
|
+
data.tar.gz: ec25f7dc4028f8ff474b83b43d9bf7df2b5b5aeeae7ceb8ff99037497a773b26
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 906562bd4c7327a0143597893ff84d9639713421f45a44878040f0bb21cf278c653843bbf8ac3e0deb493d88df9e4b8ee6bccb2600d4690d59dd30d0e82a37f5
|
|
7
|
+
data.tar.gz: 06d68142d1b583b9b8cdc520618dc62028cc5669446f728bc09033d8c96a6236131527af6e426fa20aba9313d49782a8293cb95e1ab89be1b187a722b93d8069
|
data/bin/pygmy-apple
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
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 uppygmy-apple services (dnsmasq, haproxy, mailhog, resolv, ssh-agent)'
|
|
12
|
+
long_desc <<-LONGDESC
|
|
13
|
+
Bring uppygmy-apple 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
|
+
- ssh-agent: to keep the ssh-agent at one single place, so that all other docker containers
|
|
22
|
+
can consume the ssh key. You can bypass automatically adding keys to the agent by using --no-addkey.
|
|
23
|
+
|
|
24
|
+
On Linux: The local resolver (/etc/resolv.conf) will be configured to use the dnsmasq
|
|
25
|
+
instance as a nameserver. (unless you add --no-resolver)
|
|
26
|
+
|
|
27
|
+
On Mac: A resolver file (/etc/resolver/docker.amazee.io) will be created to use the dnsmasq
|
|
28
|
+
instance as a nameserver for all *.docker.amazee.io domains. (unless you add --no-resolver)
|
|
29
|
+
|
|
30
|
+
> $pygmy-apple up
|
|
31
|
+
LONGDESC
|
|
32
|
+
option :addkey, type: :boolean, default:true
|
|
33
|
+
option :resolver, type: :boolean, default: true
|
|
34
|
+
def up
|
|
35
|
+
exec_up(options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
desc 'update', 'Pulls Docker Images and recreates the Containers'
|
|
39
|
+
long_desc <<-LONGDESC
|
|
40
|
+
Runs 'docker pull' on the Docker images in order to get their newest versions.
|
|
41
|
+
After that restarts all containers with removing them, so that the new images are used.
|
|
42
|
+
LONGDESC
|
|
43
|
+
def update
|
|
44
|
+
exec_update
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
desc 'stop', 'Stop allpygmy-apple services'
|
|
48
|
+
long_desc <<-LONGDESC
|
|
49
|
+
Stops allpygmy-apple services. Can optionally pass [-d|--destroy]
|
|
50
|
+
to destroy the containers when they stop.
|
|
51
|
+
|
|
52
|
+
> $pygmy-apple stop [-d|--destroy]
|
|
53
|
+
LONGDESC
|
|
54
|
+
option :destroy, type: :boolean, aliases: '-d', default: false
|
|
55
|
+
def stop
|
|
56
|
+
exec_stop(options)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desc 'down', 'Stop and destroy allpygmy-apple services'
|
|
60
|
+
long_desc <<-LONGDESC
|
|
61
|
+
Stops allpygmy-apple services and destroy the containers when they stop.
|
|
62
|
+
|
|
63
|
+
> $pygmy-apple down
|
|
64
|
+
LONGDESC
|
|
65
|
+
def down
|
|
66
|
+
exec_stop({:destroy => true})
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
desc 'addkey [~/.ssh/id_rsa]', 'Add additional ssh-key'
|
|
70
|
+
long_desc <<-LONGDESC
|
|
71
|
+
Adds an additional ssh key to the ssh-agent.
|
|
72
|
+
Needs the absolute path to key as an argument
|
|
73
|
+
or uses ~/.ssh/id_rsa if none provided
|
|
74
|
+
|
|
75
|
+
> $pygmy-apple addkey [~/.ssh/other_key]
|
|
76
|
+
LONGDESC
|
|
77
|
+
def addkey(key = "#{Dir.home}/.ssh/id_rsa")
|
|
78
|
+
add_ssh_key(key)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
desc 'version', 'Check current installed version ofpygmy-apple'
|
|
82
|
+
def version
|
|
83
|
+
puts "Pygmy - Version: #{Pygmy::VERSION}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
desc 'restart', 'Stop and restart allpygmy-apple services'
|
|
87
|
+
long_desc <<-LONGDESC
|
|
88
|
+
Stop and restartpygmy-apple services (dnsmasq, resolv, haproxy, mailhog, ssh-agent)
|
|
89
|
+
|
|
90
|
+
> $pygmy-apple restart [-d|--destroy]
|
|
91
|
+
LONGDESC
|
|
92
|
+
option :destroy, type: :boolean, aliases: '-d', default: false
|
|
93
|
+
def restart
|
|
94
|
+
exec_stop(options)
|
|
95
|
+
exec_up(options)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
desc 'status', 'Report status of thepygmy-apple services'
|
|
99
|
+
long_desc <<-LONGDESC
|
|
100
|
+
Checks the current status of the services managed bypygmy-apple.
|
|
101
|
+
This includes dnsmasq, mailhog, and resolv
|
|
102
|
+
|
|
103
|
+
> $pygmy-apple status
|
|
104
|
+
LONGDESC
|
|
105
|
+
def status
|
|
106
|
+
exec_status(options)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def exec_update
|
|
112
|
+
Pygmy::Haproxy.pull
|
|
113
|
+
Pygmy::Mailhog.pull
|
|
114
|
+
Pygmy::SshAgent.pull
|
|
115
|
+
Pygmy::Amazee.pull_all
|
|
116
|
+
puts "Done. Recreating containers...".yellow
|
|
117
|
+
exec_stop({:destroy => true})
|
|
118
|
+
exec_up({})
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def exec_up(options)
|
|
122
|
+
|
|
123
|
+
if options[:resolver]
|
|
124
|
+
if Pygmy::Dnsmasq.start
|
|
125
|
+
puts "Successfully started dnsmasq".green
|
|
126
|
+
else
|
|
127
|
+
puts "Error starting dnsmasq".red
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
if Pygmy::Haproxy.start
|
|
132
|
+
puts "Successfully started haproxy".green
|
|
133
|
+
else
|
|
134
|
+
puts "Error starting haproxy".red
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if Pygmy::DockerNetwork.create
|
|
138
|
+
puts "Successfully created amazeeio network".green
|
|
139
|
+
else
|
|
140
|
+
puts "Error creating amazeeio network".red
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
if Pygmy::DockerNetwork.connect
|
|
144
|
+
puts "Successfully connected haproxy to amazeeio network".green
|
|
145
|
+
else
|
|
146
|
+
puts "Error connecting haproxy to amazeeio network".red
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
if Pygmy::Mailhog.start
|
|
150
|
+
puts "Successfully started mailhog".green
|
|
151
|
+
else
|
|
152
|
+
puts "Error starting mailhog".red
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if Pygmy::SshAgent.start
|
|
156
|
+
puts "Successfully started ssh-agent".green
|
|
157
|
+
else
|
|
158
|
+
puts "Error starting ssh-agent".red
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
if options[:resolver]
|
|
162
|
+
if Pygmy::Resolv.configure
|
|
163
|
+
puts "Successfully configured local resolver".green
|
|
164
|
+
else
|
|
165
|
+
puts "Error configuring local resolver".red
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
if options[:addkey]
|
|
170
|
+
if Pygmy::SshAgentAddKey.add_ssh_key
|
|
171
|
+
puts "Successfully injected ssh key".green
|
|
172
|
+
else
|
|
173
|
+
puts "Error injecting ssh key".red
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def exec_status(_options)
|
|
179
|
+
|
|
180
|
+
if Pygmy::Dnsmasq.running?
|
|
181
|
+
puts "[*] Dnsmasq: Running as docker container #{Pygmy::Dnsmasq.container_name}".green
|
|
182
|
+
else
|
|
183
|
+
puts "[*] Dnsmasq is not running".red
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
if Pygmy::Haproxy.running?
|
|
187
|
+
puts "[*] Haproxy: Running as docker container #{Pygmy::Haproxy.container_name}".green
|
|
188
|
+
else
|
|
189
|
+
puts "[*] Haproxy is not running".red
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
if Pygmy::DockerNetwork.exists?
|
|
193
|
+
puts "[*] Network: Exists as name #{Pygmy::DockerNetwork.network_name}".green
|
|
194
|
+
else
|
|
195
|
+
puts "[*] Network does not exist".red
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
if Pygmy::DockerNetwork.haproxy_connected?
|
|
199
|
+
puts "[*] Network: Haproxy #{Pygmy::DockerNetwork.haproxy_name} connected to #{Pygmy::DockerNetwork.network_name}".green
|
|
200
|
+
else
|
|
201
|
+
puts "[*] Haproxy is not connected to #{Pygmy::DockerNetwork.network_name}".red
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
if Pygmy::Mailhog.running?
|
|
205
|
+
puts "[*] Mailhog: Running as docker container #{Pygmy::Mailhog.container_name}".green
|
|
206
|
+
else
|
|
207
|
+
puts "[*] Mailhog is not running".red
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
if Pygmy::Resolv.has_our_nameserver?
|
|
211
|
+
puts "[*] Resolv is properly configured".green
|
|
212
|
+
else
|
|
213
|
+
puts "[*] Resolv is not configured".red
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
if Pygmy::SshAgent.running?
|
|
217
|
+
puts "[*] ssh-agent: Running as docker container #{Pygmy::SshAgent.container_name}, loaded keys:".green
|
|
218
|
+
Pygmy::SshAgentAddKey.show_ssh_keys
|
|
219
|
+
else
|
|
220
|
+
puts "[*] ssh-agent is not running".red
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def add_ssh_key(key)
|
|
227
|
+
|
|
228
|
+
if Pygmy::SshAgent.running?
|
|
229
|
+
if Pygmy::SshAgentAddKey.add_ssh_key(key)
|
|
230
|
+
puts "Successfully added ssh key".green
|
|
231
|
+
else
|
|
232
|
+
puts "Error adding ssh key".red
|
|
233
|
+
end
|
|
234
|
+
else
|
|
235
|
+
puts "ssh-agent is not running, cannot add key".red
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def exec_stop(options)
|
|
241
|
+
if Pygmy::Resolv.clean
|
|
242
|
+
puts "Resolver removed".green
|
|
243
|
+
else
|
|
244
|
+
puts "Error while removing the resolver".red
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
if Pygmy::Dnsmasq.stop
|
|
248
|
+
puts "Dnsmasq container stopped".green
|
|
249
|
+
if options[:destroy]
|
|
250
|
+
if Pygmy::Dnsmasq.delete
|
|
251
|
+
puts "Dnsmasq container successfully deleted".green
|
|
252
|
+
else
|
|
253
|
+
puts "Dnsmasq container failed to delete".red
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
else
|
|
257
|
+
puts "Dnsmasq container failed to stop".red
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if Pygmy::Mailhog.stop
|
|
261
|
+
puts "Mailhog container stopped".green
|
|
262
|
+
if options[:destroy]
|
|
263
|
+
if Pygmy::Mailhog.delete
|
|
264
|
+
puts "Mailhog container successfully deleted".green
|
|
265
|
+
else
|
|
266
|
+
puts "Mailhog container failed to delete".red
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
else
|
|
270
|
+
puts "Mailhog container failed to stop".red
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
if Pygmy::SshAgent.stop
|
|
274
|
+
puts "ssh-agent container stopped".green
|
|
275
|
+
if options[:destroy]
|
|
276
|
+
if Pygmy::SshAgent.delete
|
|
277
|
+
puts "ssh-agent container successfully deleted".green
|
|
278
|
+
else
|
|
279
|
+
puts "ssh-agent container failed to delete".red
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
else
|
|
283
|
+
puts "ssh-agent container failed to stop".red
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
if Pygmy::Haproxy.stop
|
|
287
|
+
puts "Haproxy container stopped".green
|
|
288
|
+
if options[:destroy]
|
|
289
|
+
if Pygmy::Haproxy.delete
|
|
290
|
+
puts "Haproxy container successfully deleted".green
|
|
291
|
+
else
|
|
292
|
+
puts "Haproxy container failed to delete".red
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
else
|
|
296
|
+
puts "Haproxy container failed to stop".red
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
aliases = {
|
|
303
|
+
'start' => 'up',
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if !ARGV.empty? && %w[-v --version].include?(ARGV.first)
|
|
307
|
+
puts "Pygmy - Version: #{Pygmy::VERSION}"
|
|
308
|
+
else
|
|
309
|
+
PygmyBin.start(ARGV.map { |a| aliases.keys.include?(a) ? aliases[a] : a })
|
|
310
|
+
end
|
data/lib/pygmy.rb
ADDED
data/lib/pygmy/amazee.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require_relative 'docker_service'
|
|
2
|
+
require 'colorize'
|
|
3
|
+
|
|
4
|
+
module Pygmy
|
|
5
|
+
class Amazee
|
|
6
|
+
extend Pygmy::DockerService
|
|
7
|
+
|
|
8
|
+
def self.prefix
|
|
9
|
+
"amazeeio/"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.ignore_list
|
|
13
|
+
%w(none ssh-agent haproxy)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.pull(image_name)
|
|
17
|
+
puts "Pulling Docker Image #{Shellwords.escape(image_name)}".yellow
|
|
18
|
+
pull_cmd = "docker pull #{Shellwords.escape(image_name)}"
|
|
19
|
+
success = Sh.run_command(pull_cmd).success?
|
|
20
|
+
unless success
|
|
21
|
+
raise RuntimeError.new(
|
|
22
|
+
"Failed to update #{self.container_name}. Command #{pull_cmd} failed"
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.ls_cmd
|
|
28
|
+
cmd = 'docker image ls --format "{{.Repository}}:{{.Tag}}"'
|
|
29
|
+
list = Sh.run_command(cmd)
|
|
30
|
+
|
|
31
|
+
# For better handling of containers, we should compare our
|
|
32
|
+
# results against a whitelist instead of preferential
|
|
33
|
+
# treatment of linux pipes.
|
|
34
|
+
containers = list.stdout.split("\n")
|
|
35
|
+
amazee_containers = []
|
|
36
|
+
containers.each do |container|
|
|
37
|
+
# Selectively target amazeeio/* images.
|
|
38
|
+
if container.include?(self.prefix)
|
|
39
|
+
include_container = true
|
|
40
|
+
# Filter out items which we don't want.
|
|
41
|
+
self.ignore_list.each do |item|
|
|
42
|
+
if container.include?(item)
|
|
43
|
+
include_container = false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
amazee_containers.push(container) if include_container
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
amazee_containers
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.pull_all
|
|
53
|
+
list = self.ls_cmd
|
|
54
|
+
unless list.nil?
|
|
55
|
+
list.each do |image|
|
|
56
|
+
self.pull(image)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
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.78'
|
|
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 6053:53/tcp -p 6053: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
|
+
'oceanic/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
|
data/lib/pygmy/linux.rb
ADDED
|
@@ -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,32 @@
|
|
|
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
|
+
"#{Shellwords.escape(self.image_name)}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
data/lib/pygmy/resolv.rb
ADDED
|
@@ -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-apple'
|
|
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 6053
|
|
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
|
data/lib/pygmy/shell.rb
ADDED
|
@@ -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
|
metadata
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: pygmy-apple
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.9.12.pre.rc1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Michael Schmid
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-02-17 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 easily run a local Drupal development system you need more
|
|
112
|
+
than just a Docker container with Drupal running. Default development workflows
|
|
113
|
+
involve running multiple sites at the same time, interacting with other services
|
|
114
|
+
which are authenticated via ssh and more.Pygmy-apple makes sure that the required
|
|
115
|
+
Docker 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-apple
|
|
120
|
+
extensions: []
|
|
121
|
+
extra_rdoc_files: []
|
|
122
|
+
files:
|
|
123
|
+
- bin/pygmy-apple
|
|
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/version.rb
|
|
138
|
+
homepage: https://github.com/ocean/pygmy
|
|
139
|
+
licenses:
|
|
140
|
+
- MIT
|
|
141
|
+
metadata: {}
|
|
142
|
+
post_install_message:
|
|
143
|
+
rdoc_options: []
|
|
144
|
+
require_paths:
|
|
145
|
+
- lib
|
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '0'
|
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
|
+
requirements:
|
|
153
|
+
- - ">"
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: 1.3.1
|
|
156
|
+
requirements: []
|
|
157
|
+
rubygems_version: 3.2.3
|
|
158
|
+
signing_key:
|
|
159
|
+
specification_version: 4
|
|
160
|
+
summary: pygmy-apple provides the required services to run the amazee.io Drupal local
|
|
161
|
+
development environment on Apple Silicon (M1).
|
|
162
|
+
test_files: []
|