multibinder 0.0.3 → 0.0.4

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: 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