dory 0.2.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dory/config.rb +2 -0
- data/lib/dory/dnsmasq.rb +19 -8
- data/lib/dory/{linux.rb → os.rb} +3 -3
- data/lib/dory/resolv.rb +13 -70
- data/lib/dory/resolv/linux.rb +93 -0
- data/lib/dory/resolv/macos.rb +91 -0
- data/lib/dory/version.rb +2 -2
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe6595b7b6ee94069e023936a54b69aaea571ee9
|
4
|
+
data.tar.gz: df08791895d7d8b224ed912a7ddf4d8263e5532b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95dad5c161778f6acb218cb79248901b17d374b71f9828cd69f558d3e65d5752958f6b0c55200e2e8724b52cfed8f6a1cbd02a4df4db7b666c9550f6cf44b311
|
7
|
+
data.tar.gz: 3551802e1fd92fa42c9c46322b6ada62ea39574267f2b9b5d95aab917946f9fcf7af82cbdeebed56cc78a7481bda53c306ed5c2c05703ec6ad6c625b90aff043
|
data/lib/dory/config.rb
CHANGED
@@ -26,6 +26,7 @@ module Dory
|
|
26
26
|
- domain: dev
|
27
27
|
address: 127.0.0.1
|
28
28
|
container_name: dory_dnsmasq
|
29
|
+
port: 53 # port to listen for dns requests on. must be 53 on linux. can be anything that's open on macos
|
29
30
|
nginx_proxy:
|
30
31
|
enabled: true
|
31
32
|
container_name: dory_dinghy_http_proxy
|
@@ -34,6 +35,7 @@ module Dory
|
|
34
35
|
resolv:
|
35
36
|
enabled: true
|
36
37
|
nameserver: 127.0.0.1
|
38
|
+
port: 53 # port where the nameserver listens. On linux it must be 53
|
37
39
|
).split("\n").map{|s| s.sub(' ' * 8, '')}.join("\n")
|
38
40
|
end
|
39
41
|
|
data/lib/dory/dnsmasq.rb
CHANGED
@@ -6,13 +6,17 @@ module Dory
|
|
6
6
|
|
7
7
|
@@first_attempt_failed = false
|
8
8
|
|
9
|
+
def self.dnsmasq_image_name
|
10
|
+
'freedomben/dory-dnsmasq:1.1.0'
|
11
|
+
end
|
12
|
+
|
9
13
|
def self.run_preconditions
|
10
14
|
puts "[DEBUG] dnsmasq service running preconditions" if Dory::Config.debug?
|
11
15
|
|
12
16
|
# we don't want to hassle the user with checking the port unless necessary
|
13
17
|
if @@first_attempt_failed
|
14
|
-
puts "[DEBUG] First attempt failed. Checking port
|
15
|
-
listener_list = self.check_port(
|
18
|
+
puts "[DEBUG] First attempt failed. Checking port #{self.port}" if Dory::Config.debug?
|
19
|
+
listener_list = self.check_port(self.port)
|
16
20
|
unless listener_list.empty?
|
17
21
|
return self.offer_to_kill(listener_list)
|
18
22
|
end
|
@@ -36,8 +40,14 @@ module Dory
|
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
39
|
-
def self.
|
40
|
-
|
43
|
+
def self.port
|
44
|
+
return 53 unless Os.macos?
|
45
|
+
p = Dory::Config.settings[:dory][:dnsmasq][:port]
|
46
|
+
p.nil? || p == 0 ? 19323 : self.sanitize_port(p)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.sanitize_port(port)
|
50
|
+
port.to_s.gsub(/\D/, '').to_i
|
41
51
|
end
|
42
52
|
|
43
53
|
def self.container_name
|
@@ -67,14 +77,15 @@ module Dory
|
|
67
77
|
end
|
68
78
|
|
69
79
|
def self.run_command(domains = self.domains)
|
70
|
-
"docker run -d -p
|
80
|
+
"docker run -d -p #{self.port}:#{self.port}/tcp -p #{self.port}:#{self.port}/udp " \
|
81
|
+
"--name=#{Shellwords.escape(self.container_name)} " \
|
71
82
|
"--cap-add=NET_ADMIN #{Shellwords.escape(self.dnsmasq_image_name)} " \
|
72
83
|
"#{self.domain_addr_arg_string}"
|
73
84
|
end
|
74
85
|
|
75
86
|
def self.check_port(port_num)
|
76
|
-
puts "Requesting sudo to check if something is bound to port
|
77
|
-
ret = Sh.run_command(
|
87
|
+
puts "Requesting sudo to check if something is bound to port #{self.port}".green
|
88
|
+
ret = Sh.run_command("sudo lsof -i :#{self.port}")
|
78
89
|
return [] unless ret.success?
|
79
90
|
|
80
91
|
list = ret.stdout.split("\n")
|
@@ -97,7 +108,7 @@ module Dory
|
|
97
108
|
|
98
109
|
def self.offer_to_kill(listener_list, answer: nil)
|
99
110
|
listener_list.each do |process|
|
100
|
-
puts "Process '#{process.command}' with PID '#{process.pid}' is listening on #{process.node} port
|
111
|
+
puts "Process '#{process.command}' with PID '#{process.pid}' is listening on #{process.node} port #{self.port}."
|
101
112
|
end
|
102
113
|
pids = listener_list.uniq(&:pid).map(&:pid)
|
103
114
|
pidstr = pids.join(' and ')
|
data/lib/dory/{linux.rb → os.rb}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Dory
|
2
|
-
module
|
2
|
+
module Os
|
3
3
|
def self.bash(command)
|
4
4
|
system("bash -c '#{command}'")
|
5
5
|
end
|
@@ -16,9 +16,9 @@ module Dory
|
|
16
16
|
self.bash(self.arch_cmd)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
def self.macos?
|
20
20
|
self.bash('uname -a | grep "Darwin" > /dev/null')
|
21
|
-
|
21
|
+
end
|
22
22
|
|
23
23
|
def self.ubuntu_cmd
|
24
24
|
%q(
|
data/lib/dory/resolv.rb
CHANGED
@@ -2,86 +2,29 @@ require 'colorize'
|
|
2
2
|
|
3
3
|
module Dory
|
4
4
|
module Resolv
|
5
|
-
def self.
|
6
|
-
|
5
|
+
def self.get_module
|
6
|
+
return Dory::Resolv::Macos if Os.macos?
|
7
|
+
Dory::Resolv::Linux
|
7
8
|
end
|
8
9
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
12
|
-
self.common_resolv_file
|
13
|
-
end
|
10
|
+
# def self.method_missing(method_sym, *arguments, &block)
|
11
|
+
# self.get_module.send(method_sym, arguments, &block)
|
12
|
+
# end
|
14
13
|
|
15
|
-
def self.
|
16
|
-
|
17
|
-
end
|
14
|
+
# def self.respond_to?(method_sym, include_private = false)
|
15
|
+
# self.get_module.respond_to?(method_sym, include_private)
|
16
|
+
# end
|
18
17
|
|
19
|
-
def self.
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.file_nameserver_line
|
24
|
-
"nameserver #{self.nameserver}"
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.nameserver_contents
|
28
|
-
"#{self.file_nameserver_line} #{self.file_comment}"
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.resolv_file
|
32
|
-
if Linux.ubuntu?
|
33
|
-
return self.ubuntu_resolv_file if Linux.ubuntu?
|
34
|
-
elsif Linux.fedora? || Linux.arch? || File.exist?(self.common_resolv_file)
|
35
|
-
return self.common_resolv_file
|
36
|
-
else
|
37
|
-
raise RuntimeError.new(
|
38
|
-
"Unable to determine location of resolv file"
|
39
|
-
)
|
40
|
-
end
|
18
|
+
def self.has_our_nameserver?
|
19
|
+
self.get_module.has_our_nameserver?
|
41
20
|
end
|
42
21
|
|
43
22
|
def self.configure
|
44
|
-
|
45
|
-
# we only want to add the nameserver if it isn't already there
|
46
|
-
prev_conts = self.resolv_file_contents
|
47
|
-
unless self.contents_has_our_nameserver?(prev_conts)
|
48
|
-
if prev_conts =~ /nameserver/
|
49
|
-
prev_conts.sub!(/nameserver/, "#{self.nameserver_contents}\nnameserver")
|
50
|
-
else
|
51
|
-
prev_conts = "#{prev_conts}\n#{self.nameserver_contents}"
|
52
|
-
end
|
53
|
-
prev_conts.gsub!(/\s+$/, '')
|
54
|
-
self.write_to_file(prev_conts)
|
55
|
-
end
|
56
|
-
self.has_our_nameserver?
|
23
|
+
self.get_module.configure
|
57
24
|
end
|
58
25
|
|
59
26
|
def self.clean
|
60
|
-
|
61
|
-
if self.contents_has_our_nameserver?(prev_conts)
|
62
|
-
prev_conts.gsub!(/#{Regexp.escape(self.nameserver_contents + "\n")}/, '')
|
63
|
-
prev_conts.gsub!(/\s+$/, '')
|
64
|
-
self.write_to_file(prev_conts)
|
65
|
-
end
|
66
|
-
!self.has_our_nameserver?
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.write_to_file(contents)
|
70
|
-
# have to use this hack cuz we don't run as root :-(
|
71
|
-
puts "Requesting sudo to write to #{self.resolv_file}".green
|
72
|
-
Bash.run_command("echo -e '#{contents}' | sudo tee #{Shellwords.escape(self.resolv_file)} >/dev/null")
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.resolv_file_contents
|
76
|
-
File.read(self.resolv_file)
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.has_our_nameserver?
|
80
|
-
self.contents_has_our_nameserver?(self.resolv_file_contents)
|
81
|
-
end
|
82
|
-
|
83
|
-
def self.contents_has_our_nameserver?(contents)
|
84
|
-
!!((contents =~ /#{self.file_comment}/) && (contents =~ /#{self.file_nameserver_line}/))
|
27
|
+
self.get_module.clean
|
85
28
|
end
|
86
29
|
end
|
87
30
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
3
|
+
module Dory
|
4
|
+
module Resolv
|
5
|
+
module Linux
|
6
|
+
def self.common_resolv_file
|
7
|
+
'/etc/resolv.conf'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.ubuntu_resolv_file
|
11
|
+
#'/etc/resolvconf/resolv.conf.d/base'
|
12
|
+
# For now, use the common_resolv_file
|
13
|
+
self.common_resolv_file
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.file_comment
|
17
|
+
'# added by dory'
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.nameserver
|
21
|
+
Dory::Config.settings[:dory][:resolv][:nameserver]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Note that we ignore any ports present in the config
|
25
|
+
# file because only port 53 is supported on linux
|
26
|
+
# (and there's not a way to specify it in the resolv.conf
|
27
|
+
# even if we wanted to, which someday hopefully we can)
|
28
|
+
def self.file_nameserver_line
|
29
|
+
"nameserver #{self.nameserver}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.nameserver_contents
|
33
|
+
"#{self.file_nameserver_line} #{self.file_comment}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.resolv_file
|
37
|
+
if Os.ubuntu?
|
38
|
+
return self.ubuntu_resolv_file if Os.ubuntu?
|
39
|
+
elsif Os.fedora? || Os.arch? || File.exist?(self.common_resolv_file)
|
40
|
+
return self.common_resolv_file
|
41
|
+
else
|
42
|
+
raise RuntimeError.new(
|
43
|
+
"Unable to determine location of resolv file"
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.configure
|
49
|
+
# we want to be the first nameserver in the list for performance reasons
|
50
|
+
# we only want to add the nameserver if it isn't already there
|
51
|
+
prev_conts = self.resolv_file_contents
|
52
|
+
unless self.contents_has_our_nameserver?(prev_conts)
|
53
|
+
if prev_conts =~ /nameserver/
|
54
|
+
prev_conts.sub!(/nameserver/, "#{self.nameserver_contents}\nnameserver")
|
55
|
+
else
|
56
|
+
prev_conts = "#{prev_conts}\n#{self.nameserver_contents}"
|
57
|
+
end
|
58
|
+
prev_conts.gsub!(/\s+$/, '')
|
59
|
+
self.write_to_file(prev_conts)
|
60
|
+
end
|
61
|
+
self.has_our_nameserver?
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.clean
|
65
|
+
prev_conts = self.resolv_file_contents
|
66
|
+
if self.contents_has_our_nameserver?(prev_conts)
|
67
|
+
prev_conts.gsub!(/#{Regexp.escape(self.nameserver_contents + "\n")}/, '')
|
68
|
+
prev_conts.gsub!(/\s+$/, '')
|
69
|
+
self.write_to_file(prev_conts)
|
70
|
+
end
|
71
|
+
!self.has_our_nameserver?
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.write_to_file(contents)
|
75
|
+
# have to use this hack cuz we don't run as root :-(
|
76
|
+
puts "Requesting sudo to write to #{self.resolv_file}".green
|
77
|
+
Bash.run_command("echo -e '#{contents}' | sudo tee #{Shellwords.escape(self.resolv_file)} >/dev/null")
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.resolv_file_contents
|
81
|
+
File.read(self.resolv_file)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.has_our_nameserver?
|
85
|
+
self.contents_has_our_nameserver?(self.resolv_file_contents)
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.contents_has_our_nameserver?(contents)
|
89
|
+
!!((contents =~ /#{self.file_comment}/) && (contents =~ /#{self.file_nameserver_line}/))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
3
|
+
module Dory
|
4
|
+
module Resolv
|
5
|
+
module Macos
|
6
|
+
def self.system_resolv_file
|
7
|
+
'/etc/resolv.conf'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.port
|
11
|
+
Dory::Config.settings[:dory][:resolv][:port] || 19323
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.resolv_dir
|
15
|
+
'/etc/resolver'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.resolv_file_names
|
19
|
+
# on macos the file name should match the domain
|
20
|
+
if Dory::Config.settings[:dory][:dnsmasq][:domain]
|
21
|
+
[Dory::Config.settings[:dory][:dnsmasq][:domain]]
|
22
|
+
elsif Dory::Config.settings[:dory][:dnsmasq][:domains]
|
23
|
+
Dory::Config.settings[:dory][:dnsmasq][:domains].map{ |d| d[:domain] }
|
24
|
+
else
|
25
|
+
['docker']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.resolv_files
|
30
|
+
self.resolv_file_names.map{ |f| "#{self.resolv_dir}/#{f}" }
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.nameserver
|
34
|
+
Dory::Config.settings[:dory][:resolv][:nameserver]
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.file_nameserver_line
|
38
|
+
"nameserver #{self.nameserver}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.file_comment
|
42
|
+
'# added by dory'
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.resolv_contents
|
46
|
+
<<-EOF.gsub(' ' * 10, '')
|
47
|
+
#{self.file_comment}
|
48
|
+
#{self.file_nameserver_line}
|
49
|
+
port #{self.port}
|
50
|
+
EOF
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.configure
|
54
|
+
# have to use this hack cuz we don't run as root :-(
|
55
|
+
unless Dir.exist?(self.resolv_dir)
|
56
|
+
puts "Requesting sudo to create directory #{self.resolv_dir}".green
|
57
|
+
Bash.run_command("sudo mkdir -p #{self.resolv_dir}")
|
58
|
+
end
|
59
|
+
self.resolv_files.each do |filename|
|
60
|
+
puts "Requesting sudo to write to #{filename}".green
|
61
|
+
Bash.run_command("echo -e '#{self.resolv_contents}' | sudo tee #{Shellwords.escape(filename)} >/dev/null")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.clean
|
66
|
+
self.resolv_files.each do |filename|
|
67
|
+
puts "Requesting sudo to delete '#{filename}'"
|
68
|
+
Bash.run_command("sudo rm -f #{filename}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.system_resolv_file_contents
|
73
|
+
File.read(self.system_resolv_file)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.resolv_file_contents
|
77
|
+
File.read(self.resolv_file)
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.has_our_nameserver?
|
81
|
+
self.resolv_files.all? do |filename|
|
82
|
+
self.contents_has_our_nameserver?(File.read(filename))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.contents_has_our_nameserver?(contents)
|
87
|
+
!!((contents =~ /#{self.file_comment}/) && (contents =~ /#{self.file_nameserver_line}/) && (contents =~ /port.#{self.port}/))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/dory/version.rb
CHANGED
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
|
+
version: 0.3.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-06-
|
11
|
+
date: 2016-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,42 +86,42 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '11.2'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '11.2'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: byebug
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '9.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '9.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: codeclimate-test-reporter
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0.
|
117
|
+
version: '0.6'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
124
|
+
version: '0.6'
|
125
125
|
description: The slack web api is good, but very raw. What you need is a great ruby
|
126
126
|
framework to abstract away all that. This is it! This framework allows you to
|
127
127
|
write bots easily by providing methods that are easy to call. Behind the scenes,
|
@@ -140,9 +140,11 @@ files:
|
|
140
140
|
- lib/dory/config.rb
|
141
141
|
- lib/dory/dnsmasq.rb
|
142
142
|
- lib/dory/docker_service.rb
|
143
|
-
- lib/dory/
|
143
|
+
- lib/dory/os.rb
|
144
144
|
- lib/dory/proxy.rb
|
145
145
|
- lib/dory/resolv.rb
|
146
|
+
- lib/dory/resolv/linux.rb
|
147
|
+
- lib/dory/resolv/macos.rb
|
146
148
|
- lib/dory/shell.rb
|
147
149
|
- lib/dory/upgrade.rb
|
148
150
|
- lib/dory/version.rb
|
@@ -166,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
168
|
version: '0'
|
167
169
|
requirements: []
|
168
170
|
rubyforge_project:
|
169
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.4.8
|
170
172
|
signing_key:
|
171
173
|
specification_version: 4
|
172
174
|
summary: slackbot_frd provides a dirt-simple framework for implementing one or more
|