dory 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49a33137371df2a16e439572e7089d10516ae490
4
- data.tar.gz: 6a4b080407d2e8a6bbb5d6b8097f395c2aa79fad
3
+ metadata.gz: 453ef08977df972322e1995689d8b358cb6f345d
4
+ data.tar.gz: 40e16950427429b82d877302f465183f71ced5b8
5
5
  SHA512:
6
- metadata.gz: 3dbe85b3861e2ff536c0039d99c8c5447b41d7b337623f8fbe4bc0c1b51b686cb7b82f45c7d153cefb0462662d1535e23eb2019e0ebc7e2908b89635f4fdb61b
7
- data.tar.gz: 0ba2bdcd799e4cfe2537f860283b57c21d3fad48d67a69913e8bbef8bb94a70acfcca1ad32d7c10389f756eb6172132f3c5d5de124a8a74761c88a0130ec4603
6
+ metadata.gz: 8d883026dd79a18d5ec040e4df9ff81fd055f4b517071eb1ebd936f250343f71063aa05f258a0f6db084a7287a746af97a2bc457e2a4daa2b85e91f473a1e13a
7
+ data.tar.gz: d35f5e27adebcca7de68609ab7dab69e8aae9fc31705c40441a3c4f6c753d21beda006bfd5fb335b29b0a301bb7ada397f62e3c295319096812136dda2fe1400
@@ -20,13 +20,19 @@ module Dory
20
20
  # doesn't exist.
21
21
  dnsmasq:
22
22
  enabled: true
23
- domains: # array of domains that will be resolved to the specified address
23
+ domains: # array of domains that will be resolved to the specified address
24
24
  - domain: docker # you can set '#' for a wilcard
25
25
  address: 127.0.0.1 # return for queries against the domain
26
26
  - domain: dev
27
27
  address: 127.0.0.1
28
28
  container_name: dory_dnsmasq
29
29
  port: 53 # port to listen for dns requests on. must be 53 on linux. can be anything that's open on macos
30
+ # kill_others: kill processes bound to the port we need (see previous setting 'port')
31
+ # Possible values:
32
+ # ask (prompt about killing each time. User can accept/reject)
33
+ # yes|true (go aheand and kill without asking)
34
+ # no|false (don't kill, and don't even ask)
35
+ kill_others: ask
30
36
  nginx_proxy:
31
37
  enabled: true
32
38
  container_name: dory_dinghy_http_proxy
@@ -88,6 +94,9 @@ module Dory
88
94
  newsettings[:dory][:dnsmasq].delete(:address)
89
95
  end
90
96
 
97
+ # Add the option to skip prompts
98
+ newsettings[:dory][:dnsmasq][:kill_others] = 'ask'
99
+
91
100
  newsettings
92
101
  end
93
102
  end
@@ -4,7 +4,11 @@ module Dory
4
4
  class Dnsmasq
5
5
  extend Dory::DockerService
6
6
 
7
+ #
8
+ # I really hate these globals. It would be great to refactor these out
9
+ #
7
10
  @@first_attempt_failed = false
11
+ @@handle_systemd_services = false
8
12
 
9
13
  def self.dnsmasq_image_name
10
14
  'freedomben/dory-dnsmasq:1.1.0'
@@ -15,11 +19,15 @@ module Dory
15
19
 
16
20
  # we don't want to hassle the user with checking the port unless necessary
17
21
  if @@first_attempt_failed
22
+ @@handle_systemd_services = self.has_systemd? && self.has_services_that_block_dnsmasq?
23
+ self.down_systemd_services if @@handle_systemd_services
24
+
18
25
  puts "[DEBUG] First attempt failed. Checking port #{self.port}" if Dory::Config.debug?
19
26
  listener_list = self.check_port(self.port)
20
27
  unless listener_list.empty?
21
28
  return self.offer_to_kill(listener_list)
22
29
  end
30
+
23
31
  return false
24
32
  else
25
33
  puts "[DEBUG] Skipping preconditions on first run" if Dory::Config.debug?
@@ -27,6 +35,11 @@ module Dory
27
35
  end
28
36
  end
29
37
 
38
+ def self.run_postconditions
39
+ puts "[DEBUG] dnsmasq service running postconditions" if Dory::Config.debug?
40
+ self.up_systemd_services if @@handle_systemd_services
41
+ end
42
+
30
43
  def self.handle_error(command_output)
31
44
  puts "[DEBUG] handling dnsmasq start error" if Dory::Config.debug?
32
45
  # If we've already tried to handle failure, prevent infinite recursion
@@ -44,7 +57,7 @@ module Dory
44
57
  end
45
58
 
46
59
  def self.ip_from_dinghy?
47
- Dory::Dinghy.match?(self.address(self.old_address)) ||
60
+ Dory::Dinghy.match?(self.address(self.old_address)) ||
48
61
  self.domains.any?{ |domain| Dory::Dinghy.match?(self.address(domain[:address])) }
49
62
  end
50
63
 
@@ -120,20 +133,118 @@ module Dory
120
133
 
121
134
  def self.offer_to_kill(listener_list, answer: nil)
122
135
  listener_list.each do |process|
123
- puts "Process '#{process.command}' with PID '#{process.pid}' is listening on #{process.node} port #{self.port}."
136
+ puts "Process '#{process.command}' with PID '#{process.pid}' is listening on #{process.node} port #{self.port}.".yellow
124
137
  end
125
138
  pids = listener_list.uniq(&:pid).map(&:pid)
126
139
  pidstr = pids.join(' and ')
127
- print "This interferes with Dory's dnsmasq container. Would you like me to kill PID #{pidstr}? (Y/N): "
128
- conf = answer ? answer : ENV['DORY_KILL_DNSMASQ']
140
+ print "This interferes with Dory's dnsmasq container. Would you like me to kill PID #{pidstr}? (Y/N): ".yellow
141
+ conf = answer ? answer : answer_from_settings
129
142
  conf = STDIN.gets.chomp unless conf
130
143
  if conf =~ /y/i
131
- puts "Requesting sudo to kill PID #{pidstr}"
144
+ puts "Requesting sudo to kill PID #{pidstr}".green
132
145
  return Sh.run_command("sudo kill #{pids.join(' ')}").success?
133
146
  else
134
147
  puts "OK, not killing PID #{pidstr}. Please kill manually and try starting dory again.".red
135
148
  return false
136
149
  end
137
150
  end
151
+
152
+ def self.has_systemd?
153
+ Sh.run_command('which systemctl').success?
154
+ end
155
+
156
+ def self.systemd_service_installed?(service)
157
+ !(Sh.run_command("systemctl status #{service} | head -1").stdout =~ /unit.*not.*found/i)
158
+ end
159
+
160
+ def self.services_that_block_dnsmasq
161
+ %w[
162
+ NetworkManager.service
163
+ systemd-resolved.service
164
+ ]
165
+ end
166
+
167
+ def self.has_services_that_block_dnsmasq?
168
+ !self.enabled_services_that_block_dnsmasq.empty?
169
+ end
170
+
171
+ def self.enabled_services_that_block_dnsmasq
172
+ self.services_that_block_dnsmasq.select do |service|
173
+ self.systemd_service_installed?(service)
174
+ end
175
+ end
176
+
177
+ def self.down_systemd_services
178
+ puts "[DEBUG] Putting systemd services down" if Dory::Config.debug?
179
+
180
+ services = self.enabled_services_that_block_dnsmasq
181
+ conf = if ask_about_killing?
182
+ puts "You have some systemd services running that will race against us \n" \
183
+ "to bind to port 53 (and usually they win):".yellow
184
+ puts "\n #{services.join(', ')}\n".yellow
185
+ puts "If we don't stop these services temporarily while putting up the \n" \
186
+ "dnsmasq container, starting it will likely fail.".yellow
187
+ print "Would you like me to put them down while we start dns \n" \
188
+ "(I'll put them back up when finished)? (Y/N): ".yellow
189
+ STDIN.gets.chomp
190
+ else
191
+ answer_from_settings
192
+ end
193
+ @@handle_systemd_services = conf =~ /y/i
194
+ if @@handle_systemd_services
195
+ if services.all? { |service|
196
+ self.set_systemd_service(service: service, up: false)
197
+ }
198
+ puts "Putting down services succeeded".green
199
+ else
200
+ puts "One or more services failed to go down".red
201
+ end
202
+ else
203
+ puts 'OK, not putting down the services'.yellow
204
+ end
205
+ end
206
+
207
+ def self.up_systemd_services
208
+ if @@handle_systemd_services
209
+ puts "[DEBUG] Putting systemd services back up" if Dory::Config.debug?
210
+ services = self.enabled_services_that_block_dnsmasq
211
+ if services.reverse.all? { |service|
212
+ self.set_systemd_service(service: service, up: true)
213
+ }
214
+ puts "#{services.join(', ')} were successfully restarted".green
215
+ else
216
+ puts "#{services.join(', ')} failed to restart".red
217
+ end
218
+ else
219
+ puts "[DEBUG] Not putting systemd services back up cause skipped " if Dory::Config.debug?
220
+ end
221
+ end
222
+
223
+ def self.set_systemd_service(service:, up:)
224
+ action = up ? 'start' : 'stop'
225
+ puts "Requesting sudo to #{action} #{service}".green
226
+ Sh.run_command("sudo systemctl #{action} #{service}").success?
227
+ end
228
+
229
+ def self.ask_about_killing?
230
+ !self.answer_from_settings
231
+ end
232
+
233
+ def self.kill_others
234
+ Dory::Config.settings[:dory][:dnsmasq][:kill_others]
235
+ end
236
+
237
+ def self.answer_from_settings
238
+ # This `== true` is important because kill_others could be
239
+ # 'no' which would be a truthy value despite the fact that it
240
+ # should be falsey
241
+ if self.kill_others == true || self.kill_others =~ /yes/i
242
+ 'Y'
243
+ elsif self.kill_others == false || self.kill_others =~ /no/i
244
+ 'N'
245
+ else
246
+ nil
247
+ end
248
+ end
138
249
  end
139
250
  end
@@ -16,6 +16,11 @@ module Dory
16
16
  return true
17
17
  end
18
18
 
19
+ def run_postconditions
20
+ # Override if postconditions are needed
21
+ return true
22
+ end
23
+
19
24
  def handle_error(command_output)
20
25
  # Override to provide error handling
21
26
  return false
@@ -28,26 +33,10 @@ module Dory
28
33
  end
29
34
  else
30
35
  if docker_installed?
36
+ self.delete_container_if_exists
31
37
  self.run_preconditions
32
- if self.container_exists?
33
- puts "[DEBUG] Container '#{self.container_name}' exists. Deleting" if Dory::Config.debug?
34
- self.delete
35
- end
36
- begin
37
- if Dory::Config.debug?
38
- puts "[DEBUG] '#{self.container_name}' does not exist. Creating/starting " \
39
- "'#{self.container_name}' with '#{self.run_command}'"
40
- end
41
- status = Sh.run_command(self.run_command)
42
- unless status.success?
43
- if !handle_error || !self.handle_error(status)
44
- puts "Failed to start docker container '#{self.container_name}' " \
45
- ". Command '#{self.run_command}' failed".red
46
- end
47
- end
48
- rescue DinghyError => e
49
- puts e.message.red
50
- end
38
+ self.execute_run_command(handle_error: handle_error)
39
+ self.run_postconditions
51
40
  else
52
41
  err_msg = "Docker does not appear to be installed /o\\\n" \
53
42
  "Docker is required for DNS and Nginx proxy. These can be " \
@@ -93,5 +82,31 @@ module Dory
93
82
  def start_cmd
94
83
  "docker start #{Shellwords.escape(self.container_name)}"
95
84
  end
85
+
86
+ def delete_container_if_exists
87
+ if self.container_exists?
88
+ puts "[DEBUG] Container '#{self.container_name}' exists. Deleting" if Dory::Config.debug?
89
+ self.delete
90
+ end
91
+ end
92
+
93
+ def execute_run_command(handle_error:)
94
+ begin
95
+ if Dory::Config.debug?
96
+ puts "[DEBUG] '#{self.container_name}' does not exist. Creating/starting " \
97
+ "'#{self.container_name}' with '#{self.run_command}'"
98
+ end
99
+ status = Sh.run_command(self.run_command)
100
+ unless status.success?
101
+ if !handle_error || !self.handle_error(status)
102
+ puts "Failed to start docker container '#{self.container_name}' " \
103
+ ". Command '#{self.run_command}' failed".red
104
+ end
105
+ end
106
+ rescue Dory::Dinghy::DinghyError => e
107
+ puts e.message.red
108
+ end
109
+ status
110
+ end
96
111
  end
97
112
  end
@@ -1,4 +1,4 @@
1
1
  module Dory
2
- VERSION = '0.4.2'
3
- DATE = '2016-02-08'
2
+ VERSION = '0.5.0'
3
+ DATE = '2016-02-13'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Porter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-08 00:00:00.000000000 Z
11
+ date: 2016-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize