dory 0.4.2 → 0.5.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 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