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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 018cdd17d26576620f14c20c1f8070017bd43d29
4
- data.tar.gz: dbf623adb438d0bb13255aa339bb38a0738371b6
3
+ metadata.gz: 00e47bebe4eec94c83ac430fb7d6c887e9159436
4
+ data.tar.gz: 5d839a52f9d793ca4c003dbcba8c2f5c5e3b97f9
5
5
  SHA512:
6
- metadata.gz: 49abc85df2ce0e87c6cc407922746087df99332aafdbf181564d87e6b4458e529f553105d5521df92ca11ca50f491dd0d1cd24aabc8dfcbe660e7d4f3c504c8e
7
- data.tar.gz: 45e8ee754b2cc547c5e12013b68a633ba4b187ed13ec6fadd7711c9d39a25def4f76f98de160412bd202a1e983c3404dbc2a6273e3ed64024892cbbd6581b4b6
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
@@ -0,0 +1,10 @@
1
+ [Unit]
2
+ Description=Multibinder
3
+ After=network.target
4
+
5
+ [Service]
6
+ ExecStart=/usr/local/bin/multibinder /run/multibinder.sock
7
+ Restart=always
8
+
9
+ [Install]
10
+ WantedBy=multi-user.target
@@ -1,3 +1,3 @@
1
1
  module MultiBinder
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
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.3
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-04-07 00:00:00.000000000 Z
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.0.14
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