multibinder 0.0.3 → 0.0.4
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 +4 -4
- data/bin/multibinder-haproxy-erb +40 -0
- data/bin/multibinder-haproxy-wrapper +64 -0
- data/haproxy/haproxy-multi@.service +20 -0
- data/haproxy/multibinder.service +10 -0
- data/lib/multibinder/version.rb +1 -1
- metadata +16 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00e47bebe4eec94c83ac430fb7d6c887e9159436
|
4
|
+
data.tar.gz: 5d839a52f9d793ca4c003dbcba8c2f5c5e3b97f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbb81e35458b82592b48cf48d6250c796640a94072995f359c54ee08a9d173717442bc518e4e82d758cd437f6796387a9e5e40cfc82de2f054d52869fbdc018e
|
7
|
+
data.tar.gz: 9dc6ea20ad3ffdb185c2c7a90ff1cd553449356f5952679258418b4e89674cf26e8fab62a02e7b539d892f42300abaddaa71c6897ac04d30920755e516962abd
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Takes arguments that will be fed to haproxy, but sneakily tweaks the argument
|
3
|
+
# to '-f' by ERB-parsing it and then providing the result.
|
4
|
+
|
5
|
+
require 'multibinder'
|
6
|
+
require 'socket'
|
7
|
+
require 'fcntl'
|
8
|
+
require 'erb'
|
9
|
+
|
10
|
+
haproxy_call = ARGV
|
11
|
+
|
12
|
+
# find and update '-f' argument to the output of ERB processing
|
13
|
+
abort 'multibinder-haproxy expects a configuration file to be passed to haproxy' if haproxy_call.index('-f').nil?
|
14
|
+
config_file_index = haproxy_call.index('-f') + 1
|
15
|
+
haproxy_erb = haproxy_call[config_file_index]
|
16
|
+
abort 'Config file must end with .erb' unless haproxy_erb.end_with? '.erb'
|
17
|
+
haproxy_cfg = haproxy_erb.sub('.erb', '')
|
18
|
+
haproxy_call[config_file_index] = haproxy_cfg
|
19
|
+
|
20
|
+
def bind_tcp(ip, port)
|
21
|
+
if ENV['MULTIBINDER_SOCK'] && !ENV['MULTIBINDER_SOCK'].empty?
|
22
|
+
# if we have multibinder, use it to reuse our binds safely
|
23
|
+
server = MultiBinder.bind ip, port, { :backlog => 10240 }
|
24
|
+
"fd@#{server.fileno}"
|
25
|
+
else
|
26
|
+
# otherwise resort to the old fashioned binds with downtime/packet loss
|
27
|
+
puts "WARNING: Using haproxy direct binds, restarts will cause error!"
|
28
|
+
"#{ip}:#{port}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
new_data = ERB.new(File.read(haproxy_erb)).result
|
33
|
+
File.write(haproxy_cfg, new_data)
|
34
|
+
|
35
|
+
if haproxy_call.index('--erb-write-only')
|
36
|
+
puts 'ERB config write requested without launching command, exiting.'
|
37
|
+
exit 0
|
38
|
+
end
|
39
|
+
|
40
|
+
Process.exec *haproxy_call, :close_others => false
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Runs multibinder-haproxy-erb with the same arguments, supporting a USR2 for reload.
|
3
|
+
|
4
|
+
dir = File.expand_path(File.dirname(__FILE__))
|
5
|
+
$launch_haproxy = File.join(dir, "multibinder-haproxy-erb")
|
6
|
+
|
7
|
+
SERVICE_DIR = File.basename(dir)
|
8
|
+
SERVICE_NAME = SERVICE_DIR.split('-').drop(1).join('-')
|
9
|
+
|
10
|
+
abort 'multibinder-haproxy-wrapper expects a pid file to be passed to haproxy' if ARGV.index('-p').nil?
|
11
|
+
pid_file_index = ARGV.index('-p') + 1
|
12
|
+
$PID_FILE = ARGV[pid_file_index]
|
13
|
+
|
14
|
+
# launches a new instance. the haproxy-instance script automatically handles
|
15
|
+
# everything: when no existing pid exists, it starts haproxy normally. when
|
16
|
+
# an existing haproxy is running, it calls a new copy with `-sf` so that
|
17
|
+
# haproxy safely hands over execution to the new process.
|
18
|
+
def launch_instance
|
19
|
+
args = [$launch_haproxy] + ARGV
|
20
|
+
if File.exist? $PID_FILE
|
21
|
+
args << "-sf"
|
22
|
+
args.concat File.read($PID_FILE).split()
|
23
|
+
end
|
24
|
+
|
25
|
+
Process.spawn *args
|
26
|
+
end
|
27
|
+
|
28
|
+
def cleanup_existing
|
29
|
+
if File.exist? $PID_FILE
|
30
|
+
`kill -USR1 $(cat #{$PID_FILE}); rm #{$PID_FILE}`
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# A SIGUSR2 tells us to safely relaunch
|
35
|
+
Signal.trap("USR2") do
|
36
|
+
old_pids = File.read($PID_FILE)
|
37
|
+
|
38
|
+
launch_instance
|
39
|
+
|
40
|
+
# wait a while for the pid file to change. after a while, give up and unblock reloads
|
41
|
+
for i in 0..20
|
42
|
+
break if File.read($PID_FILE) != old_pids
|
43
|
+
sleep 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# If we try to kill haproxy, have them gracefully quit rather than terminate immediately
|
48
|
+
Signal.trap("TERM") do
|
49
|
+
cleanup_existing
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
|
53
|
+
# Start the first process itself
|
54
|
+
launch_instance
|
55
|
+
|
56
|
+
# Keep waitpid()ing forever.
|
57
|
+
begin
|
58
|
+
loop do
|
59
|
+
Process.waitpid
|
60
|
+
sleep 10
|
61
|
+
end
|
62
|
+
ensure
|
63
|
+
cleanup_existing
|
64
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=HAProxy Load Balancer
|
3
|
+
Documentation=man:haproxy(1)
|
4
|
+
Documentation=file:/usr/share/doc/haproxy/configuration.txt.gz
|
5
|
+
After=network.target syslog.service multibinder.service
|
6
|
+
Wants=syslog.service multibinder.service
|
7
|
+
|
8
|
+
[Service]
|
9
|
+
Environment=CONFIG=/etc/haproxy/%i.cfg.erb
|
10
|
+
Environment=MULTIBINDER_SOCK=/run/multibinder.sock
|
11
|
+
EnvironmentFile=-/etc/default/haproxy
|
12
|
+
ExecStartPre=/usr/local/bin/multibinder-haproxy-erb /usr/sbin/haproxy -f ${CONFIG} -c -q
|
13
|
+
ExecStart=/usr/local/bin/multibinder-haproxy-wrapper /usr/sbin/haproxy -Ds -f ${CONFIG} -p /run/haproxy-%i.pid $EXTRAOPTS
|
14
|
+
ExecReload=/bin/sh -c "/usr/local/bin/multibinder-haproxy-erb /usr/sbin/haproxy -c -f ${CONFIG}; /bin/kill -USR2 $MAINPID"
|
15
|
+
ExecStop=/bin/kill -TERM $MAINPID
|
16
|
+
KillMode=none
|
17
|
+
Restart=always
|
18
|
+
|
19
|
+
[Install]
|
20
|
+
WantedBy=multi-user.target
|
data/lib/multibinder/version.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multibinder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Julienne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
description:
|
@@ -43,15 +43,21 @@ email:
|
|
43
43
|
- theojulienne@github.com
|
44
44
|
executables:
|
45
45
|
- multibinder
|
46
|
+
- multibinder-haproxy-erb
|
47
|
+
- multibinder-haproxy-wrapper
|
46
48
|
extensions: []
|
47
49
|
extra_rdoc_files: []
|
48
50
|
files:
|
49
|
-
- .gitignore
|
51
|
+
- ".gitignore"
|
50
52
|
- Gemfile
|
51
53
|
- LICENSE.txt
|
52
54
|
- README.md
|
53
55
|
- Rakefile
|
54
56
|
- bin/multibinder
|
57
|
+
- bin/multibinder-haproxy-erb
|
58
|
+
- bin/multibinder-haproxy-wrapper
|
59
|
+
- haproxy/haproxy-multi@.service
|
60
|
+
- haproxy/multibinder.service
|
55
61
|
- lib/multibinder.rb
|
56
62
|
- lib/multibinder/version.rb
|
57
63
|
- multibinder.gemspec
|
@@ -74,17 +80,17 @@ require_paths:
|
|
74
80
|
- lib
|
75
81
|
required_ruby_version: !ruby/object:Gem::Requirement
|
76
82
|
requirements:
|
77
|
-
- -
|
83
|
+
- - ">="
|
78
84
|
- !ruby/object:Gem::Version
|
79
85
|
version: '0'
|
80
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
87
|
requirements:
|
82
|
-
- -
|
88
|
+
- - ">="
|
83
89
|
- !ruby/object:Gem::Version
|
84
90
|
version: '0'
|
85
91
|
requirements: []
|
86
92
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.
|
93
|
+
rubygems_version: 2.2.3
|
88
94
|
signing_key:
|
89
95
|
specification_version: 4
|
90
96
|
summary: multibinder is a tiny ruby server that makes writing zero-downtime-reload
|