haproxyctl 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rubocop.yml +1 -0
- data/LICENSE +1 -1
- data/README.md +16 -5
- data/bin/haproxyctl +48 -48
- data/haproxyctl +48 -48
- data/install-haproxy/haproxy_src_install.sh +1 -1
- data/lib/haproxyctl.rb +21 -22
- data/lib/haproxyctl/environment.rb +6 -6
- data/lib/haproxyctl/version.rb +1 -1
- data/rhapr/Rakefile +1 -1
- data/rhapr/lib/rhapr/environment.rb +6 -6
- data/rhapr/lib/rhapr/interface.rb +16 -16
- data/rhapr/rhapr.gemspec +2 -2
- data/rhapr/spec/quality_spec.rb +1 -1
- data/rhapr/spec/rhapr/environment_spec.rb +4 -4
- data/rhapr/spec/rhapr/interface_spec.rb +9 -10
- data/rhapr/spec/spec_helper.rb +1 -1
- data/rhapr/spec/support/config_fixtures.rb +4 -4
- data/rhapr/spec/support/custom_matchers.rb +3 -3
- data/rubocop-todo.yml +74 -0
- metadata +4 -2
data/.rubocop.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
inherit_from: rubocop-todo.yml
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -11,17 +11,20 @@ This is a simple wrapper to make life with HAProxy a little more convenient.
|
|
11
11
|
|
12
12
|
[Here](http://scale10x.biggiantnerds.com) is a presentation about it.
|
13
13
|
|
14
|
+
|
14
15
|
Installation
|
15
16
|
------------
|
16
17
|
|
17
18
|
On most UNIX, assuming HAProxy is in the $PATH:
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
<pre>
|
20
|
+
git clone git@github.com:flores/haproxyctl.git
|
21
|
+
ln -s haproxyctl/haproxyctl /etc/init.d/haproxyctl
|
22
|
+
</pre>
|
21
23
|
|
22
24
|
For chkconfig/RedHat/Centos, add:
|
23
|
-
|
24
|
-
|
25
|
+
<pre>
|
26
|
+
chkconfig --add haproxyctl
|
27
|
+
</pre>
|
25
28
|
|
26
29
|
There is also an HAProxy source installation script. This installs not only the steps above but latest HAProxy sources!
|
27
30
|
|
@@ -344,6 +347,14 @@ Contributors
|
|
344
347
|
- [deniedboarding](https://github.com/deniedboarding)
|
345
348
|
- [Aaron Blew aka `blewa`](https://github.com/blewa)
|
346
349
|
- [Nick Griffiths aka `nicobrevin`](https://github.com/nicobrevin)
|
350
|
+
- [Florian Holzhauer aka `fh`](https://github.com/fh)
|
351
|
+
|
352
|
+
|
353
|
+
Non-current HAProxy versions
|
354
|
+
------------
|
355
|
+
Be aware that HAProxy below current stable (1.4) does not support many of the
|
356
|
+
options of haproxyctl.
|
357
|
+
|
347
358
|
|
348
359
|
License
|
349
360
|
-----------------
|
data/bin/haproxyctl
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
|
14
14
|
require 'pathname'
|
15
15
|
lib = File.join(File.dirname(Pathname.new(__FILE__).realpath), '../lib')
|
16
|
-
|
16
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
17
17
|
|
18
18
|
require 'haproxyctl'
|
19
19
|
include HAProxyCTL
|
@@ -23,70 +23,70 @@ argument = ARGV.join(' ')
|
|
23
23
|
unless has_exec?
|
24
24
|
puts usage if argument =~ /help/ || ARGV.length < 1
|
25
25
|
|
26
|
-
|
26
|
+
fail 'Cannot find haproxy executable. Please ensure it is in your $PATH, or set $HAPROXY_BIN environment variable.'
|
27
27
|
end
|
28
28
|
|
29
29
|
display_usage! if argument =~ /help/ || ARGV.length < 1
|
30
30
|
|
31
31
|
begin
|
32
32
|
case argument
|
33
|
-
when
|
33
|
+
when 'start'
|
34
34
|
if pidof
|
35
|
-
|
35
|
+
fail("haproxy is already running on pid #{pidof}!")
|
36
36
|
else
|
37
37
|
start
|
38
38
|
end
|
39
|
-
when
|
39
|
+
when 'stop'
|
40
40
|
stop(check_running)
|
41
|
-
when
|
41
|
+
when 'restart'
|
42
42
|
if pidof
|
43
43
|
stop(pidof)
|
44
|
-
stillpidof = check_running
|
44
|
+
stillpidof = check_running
|
45
45
|
while stillpidof == pidof
|
46
46
|
puts "still haven't killed old pid. waiting 3s for existing connections to die... (ctrl+c to stop)"
|
47
47
|
sleep 3
|
48
|
-
stillpidof = check_running
|
48
|
+
stillpidof = check_running || 0
|
49
49
|
end
|
50
|
-
start
|
50
|
+
start
|
51
51
|
else
|
52
|
-
puts
|
53
|
-
start
|
52
|
+
puts 'haproxy was not running. starting...'
|
53
|
+
start
|
54
54
|
end
|
55
|
-
when
|
56
|
-
if
|
55
|
+
when 'reload'
|
56
|
+
if pidof
|
57
57
|
reload(pidof)
|
58
58
|
else
|
59
|
-
puts
|
60
|
-
start
|
59
|
+
puts 'haproxy not running. starting...'
|
60
|
+
start
|
61
61
|
end
|
62
|
-
when
|
63
|
-
if
|
62
|
+
when 'status'
|
63
|
+
if pidof
|
64
64
|
puts "haproxy is running on pid #{pidof}.\nthese ports are used and guys are connected:"
|
65
65
|
system("lsof -ln -i |awk \'$2 ~ /#{pidof}/ {print $8\" \"$9}\'")
|
66
66
|
else
|
67
|
-
puts
|
67
|
+
puts 'haproxy is not running'
|
68
68
|
end
|
69
|
-
when
|
69
|
+
when 'configcheck'
|
70
70
|
puts `#{exec} -c -f #{config_path}`
|
71
|
-
when
|
72
|
-
if
|
73
|
-
puts
|
71
|
+
when 'nagios'
|
72
|
+
if pidof
|
73
|
+
puts 'OK'
|
74
74
|
exit
|
75
75
|
else
|
76
|
-
puts
|
76
|
+
puts 'CRITICAL: HAProxy is not running!'
|
77
77
|
exit(2)
|
78
78
|
end
|
79
|
-
when
|
80
|
-
if
|
81
|
-
puts
|
79
|
+
when 'cloudkick'
|
80
|
+
if pidof
|
81
|
+
puts 'status ok haproxy is running'
|
82
82
|
conn = `lsof -ln -i |grep -c #{pidof}`.chomp.to_i
|
83
83
|
# removes the listener
|
84
84
|
conn = conn - 1
|
85
85
|
puts "metric connections int #{conn}"
|
86
|
-
status=unixsock(
|
86
|
+
status = unixsock('show stat')
|
87
87
|
status.each do |line|
|
88
88
|
line = line.split(',')
|
89
|
-
if
|
89
|
+
if line[0] !~ /^#/
|
90
90
|
host = "#{line[0]}_#{line[1]}"
|
91
91
|
puts "metric #{host}_request_rate int #{line[47]}" if line[47].to_i > 0
|
92
92
|
puts "metric #{host}_total_requests gauge #{line[49]}" if line[49].to_i > 0
|
@@ -95,59 +95,59 @@ begin
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
else
|
98
|
-
puts
|
98
|
+
puts 'status err haproxy is not running!'
|
99
99
|
end
|
100
|
-
when
|
101
|
-
status=unixsock(
|
100
|
+
when 'show health'
|
101
|
+
status = unixsock('show stat')
|
102
102
|
status.each do |line|
|
103
103
|
data = line.split(',')
|
104
104
|
printf "%-30s %-30s %-7s %3s\n", data[0], data[1], data[17], data[18]
|
105
105
|
end
|
106
106
|
when /show backend(s?)/
|
107
|
-
status=unixsock(
|
107
|
+
status = unixsock('show stat').grep(/BACKEND/)
|
108
108
|
status.each do |line|
|
109
109
|
data = line.split(',')
|
110
110
|
printf "%-30s %-30s %-7s %3s\n", data[0], data[1], data[17], data[18]
|
111
111
|
end
|
112
112
|
when /disable all EXCEPT (.+)/
|
113
|
-
servername
|
114
|
-
status=unixsock(
|
113
|
+
servername = Regexp.last_match[ 1]
|
114
|
+
status = unixsock('show stat')
|
115
115
|
backend = status.grep(/#{servername}/)
|
116
116
|
backend.each do |line|
|
117
117
|
backend_group = line.split(',')
|
118
118
|
status.each do |pool|
|
119
119
|
data = pool.split(',')
|
120
|
-
if
|
120
|
+
if (data[0] == backend_group[0]) && ( data[1] !~ /#{servername}|BACKEND|FRONTEND/) && ( data[17] == 'UP')
|
121
121
|
unixsock("disable server #{data[0]}/#{data[1]}")
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
125
125
|
when /disable all (.+)/
|
126
|
-
servername
|
127
|
-
status=unixsock(
|
126
|
+
servername = Regexp.last_match[ 1]
|
127
|
+
status = unixsock('show stat')
|
128
128
|
status.each do |line|
|
129
129
|
data = line.split(',')
|
130
|
-
if
|
130
|
+
if ( data[1] == servername) && ( data[17] == 'UP')
|
131
131
|
unixsock("disable server #{data[0]}/#{servername}")
|
132
132
|
end
|
133
133
|
end
|
134
134
|
when /enable all EXCEPT (.+)/
|
135
|
-
servername
|
136
|
-
status=unixsock(
|
135
|
+
servername = Regexp.last_match[ 1]
|
136
|
+
status = unixsock('show stat')
|
137
137
|
backend = status.grep(/#{servername}/)
|
138
138
|
backend.each do |line|
|
139
139
|
backend_group = line.split(',')
|
140
140
|
status.each do |pool|
|
141
141
|
data = pool.split(',')
|
142
|
-
if
|
142
|
+
if (data[0] == backend_group[0]) && ( data[1] !~ /#{servername}|BACKEND|FRONTEND/) && ( data[17] =~ /Down|MAINT/i)
|
143
143
|
unixsock("enable server #{data[0]}/#{data[1]}")
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
147
147
|
when /show stat (.+)/
|
148
|
-
fieldnames
|
149
|
-
status=unixsock(
|
150
|
-
indices = fieldnames.split(
|
148
|
+
fieldnames = Regexp.last_match[ 1]
|
149
|
+
status = unixsock('show stat')
|
150
|
+
indices = fieldnames.split(' ').map do |name|
|
151
151
|
status.first.split(',').index(name) || begin
|
152
152
|
$stderr.puts("no such field: #{name}")
|
153
153
|
$stderr.puts(" #{status.first}")
|
@@ -156,15 +156,15 @@ begin
|
|
156
156
|
end
|
157
157
|
status[1..-1].each do |line|
|
158
158
|
row = line.split(',')
|
159
|
-
filtered = indices.map {|index| row[index] }
|
159
|
+
filtered = indices.map { |index| row[index] }
|
160
160
|
puts (row[0...2] + filtered).compact.join(',')
|
161
161
|
end
|
162
162
|
when /enable all (.+)/
|
163
|
-
servername
|
164
|
-
status=unixsock(
|
163
|
+
servername = Regexp.last_match[ 1]
|
164
|
+
status = unixsock('show stat')
|
165
165
|
status.each do |line|
|
166
166
|
data = line.split(',')
|
167
|
-
if
|
167
|
+
if ( data[1] == servername) && ( data[17] =~ /Down|MAINT/i)
|
168
168
|
unixsock("enable server #{data[0]}/#{servername}")
|
169
169
|
end
|
170
170
|
end
|
data/haproxyctl
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
|
14
14
|
require 'pathname'
|
15
15
|
lib = File.join(File.dirname(Pathname.new(__FILE__).realpath), '../lib')
|
16
|
-
|
16
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
17
17
|
|
18
18
|
require 'haproxyctl'
|
19
19
|
include HAProxyCTL
|
@@ -23,70 +23,70 @@ argument = ARGV.join(' ')
|
|
23
23
|
unless has_exec?
|
24
24
|
puts usage if argument =~ /help/ || ARGV.length < 1
|
25
25
|
|
26
|
-
|
26
|
+
fail 'Cannot find haproxy executable. Please ensure it is in your $PATH, or set $HAPROXY_BIN environment variable.'
|
27
27
|
end
|
28
28
|
|
29
29
|
display_usage! if argument =~ /help/ || ARGV.length < 1
|
30
30
|
|
31
31
|
begin
|
32
32
|
case argument
|
33
|
-
when
|
33
|
+
when 'start'
|
34
34
|
if pidof
|
35
|
-
|
35
|
+
fail("haproxy is already running on pid #{pidof}!")
|
36
36
|
else
|
37
37
|
start
|
38
38
|
end
|
39
|
-
when
|
39
|
+
when 'stop'
|
40
40
|
stop(check_running)
|
41
|
-
when
|
41
|
+
when 'restart'
|
42
42
|
if pidof
|
43
43
|
stop(pidof)
|
44
|
-
stillpidof = check_running
|
44
|
+
stillpidof = check_running
|
45
45
|
while stillpidof == pidof
|
46
46
|
puts "still haven't killed old pid. waiting 3s for existing connections to die... (ctrl+c to stop)"
|
47
47
|
sleep 3
|
48
|
-
stillpidof = check_running
|
48
|
+
stillpidof = check_running || 0
|
49
49
|
end
|
50
|
-
start
|
50
|
+
start
|
51
51
|
else
|
52
|
-
puts
|
53
|
-
start
|
52
|
+
puts 'haproxy was not running. starting...'
|
53
|
+
start
|
54
54
|
end
|
55
|
-
when
|
56
|
-
if
|
55
|
+
when 'reload'
|
56
|
+
if pidof
|
57
57
|
reload(pidof)
|
58
58
|
else
|
59
|
-
puts
|
60
|
-
start
|
59
|
+
puts 'haproxy not running. starting...'
|
60
|
+
start
|
61
61
|
end
|
62
|
-
when
|
63
|
-
if
|
62
|
+
when 'status'
|
63
|
+
if pidof
|
64
64
|
puts "haproxy is running on pid #{pidof}.\nthese ports are used and guys are connected:"
|
65
65
|
system("lsof -ln -i |awk \'$2 ~ /#{pidof}/ {print $8\" \"$9}\'")
|
66
66
|
else
|
67
|
-
puts
|
67
|
+
puts 'haproxy is not running'
|
68
68
|
end
|
69
|
-
when
|
69
|
+
when 'configcheck'
|
70
70
|
puts `#{exec} -c -f #{config_path}`
|
71
|
-
when
|
72
|
-
if
|
73
|
-
puts
|
71
|
+
when 'nagios'
|
72
|
+
if pidof
|
73
|
+
puts 'OK'
|
74
74
|
exit
|
75
75
|
else
|
76
|
-
puts
|
76
|
+
puts 'CRITICAL: HAProxy is not running!'
|
77
77
|
exit(2)
|
78
78
|
end
|
79
|
-
when
|
80
|
-
if
|
81
|
-
puts
|
79
|
+
when 'cloudkick'
|
80
|
+
if pidof
|
81
|
+
puts 'status ok haproxy is running'
|
82
82
|
conn = `lsof -ln -i |grep -c #{pidof}`.chomp.to_i
|
83
83
|
# removes the listener
|
84
84
|
conn = conn - 1
|
85
85
|
puts "metric connections int #{conn}"
|
86
|
-
status=unixsock(
|
86
|
+
status = unixsock('show stat')
|
87
87
|
status.each do |line|
|
88
88
|
line = line.split(',')
|
89
|
-
if
|
89
|
+
if line[0] !~ /^#/
|
90
90
|
host = "#{line[0]}_#{line[1]}"
|
91
91
|
puts "metric #{host}_request_rate int #{line[47]}" if line[47].to_i > 0
|
92
92
|
puts "metric #{host}_total_requests gauge #{line[49]}" if line[49].to_i > 0
|
@@ -95,59 +95,59 @@ begin
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
else
|
98
|
-
puts
|
98
|
+
puts 'status err haproxy is not running!'
|
99
99
|
end
|
100
|
-
when
|
101
|
-
status=unixsock(
|
100
|
+
when 'show health'
|
101
|
+
status = unixsock('show stat')
|
102
102
|
status.each do |line|
|
103
103
|
data = line.split(',')
|
104
104
|
printf "%-30s %-30s %-7s %3s\n", data[0], data[1], data[17], data[18]
|
105
105
|
end
|
106
106
|
when /show backend(s?)/
|
107
|
-
status=unixsock(
|
107
|
+
status = unixsock('show stat').grep(/BACKEND/)
|
108
108
|
status.each do |line|
|
109
109
|
data = line.split(',')
|
110
110
|
printf "%-30s %-30s %-7s %3s\n", data[0], data[1], data[17], data[18]
|
111
111
|
end
|
112
112
|
when /disable all EXCEPT (.+)/
|
113
|
-
servername
|
114
|
-
status=unixsock(
|
113
|
+
servername = Regexp.last_match[ 1]
|
114
|
+
status = unixsock('show stat')
|
115
115
|
backend = status.grep(/#{servername}/)
|
116
116
|
backend.each do |line|
|
117
117
|
backend_group = line.split(',')
|
118
118
|
status.each do |pool|
|
119
119
|
data = pool.split(',')
|
120
|
-
if
|
120
|
+
if (data[0] == backend_group[0]) && ( data[1] !~ /#{servername}|BACKEND|FRONTEND/) && ( data[17] == 'UP')
|
121
121
|
unixsock("disable server #{data[0]}/#{data[1]}")
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
125
125
|
when /disable all (.+)/
|
126
|
-
servername
|
127
|
-
status=unixsock(
|
126
|
+
servername = Regexp.last_match[ 1]
|
127
|
+
status = unixsock('show stat')
|
128
128
|
status.each do |line|
|
129
129
|
data = line.split(',')
|
130
|
-
if
|
130
|
+
if ( data[1] == servername) && ( data[17] == 'UP')
|
131
131
|
unixsock("disable server #{data[0]}/#{servername}")
|
132
132
|
end
|
133
133
|
end
|
134
134
|
when /enable all EXCEPT (.+)/
|
135
|
-
servername
|
136
|
-
status=unixsock(
|
135
|
+
servername = Regexp.last_match[ 1]
|
136
|
+
status = unixsock('show stat')
|
137
137
|
backend = status.grep(/#{servername}/)
|
138
138
|
backend.each do |line|
|
139
139
|
backend_group = line.split(',')
|
140
140
|
status.each do |pool|
|
141
141
|
data = pool.split(',')
|
142
|
-
if
|
142
|
+
if (data[0] == backend_group[0]) && ( data[1] !~ /#{servername}|BACKEND|FRONTEND/) && ( data[17] =~ /Down|MAINT/i)
|
143
143
|
unixsock("enable server #{data[0]}/#{data[1]}")
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
147
147
|
when /show stat (.+)/
|
148
|
-
fieldnames
|
149
|
-
status=unixsock(
|
150
|
-
indices = fieldnames.split(
|
148
|
+
fieldnames = Regexp.last_match[ 1]
|
149
|
+
status = unixsock('show stat')
|
150
|
+
indices = fieldnames.split(' ').map do |name|
|
151
151
|
status.first.split(',').index(name) || begin
|
152
152
|
$stderr.puts("no such field: #{name}")
|
153
153
|
$stderr.puts(" #{status.first}")
|
@@ -156,15 +156,15 @@ begin
|
|
156
156
|
end
|
157
157
|
status[1..-1].each do |line|
|
158
158
|
row = line.split(',')
|
159
|
-
filtered = indices.map {|index| row[index] }
|
159
|
+
filtered = indices.map { |index| row[index] }
|
160
160
|
puts (row[0...2] + filtered).compact.join(',')
|
161
161
|
end
|
162
162
|
when /enable all (.+)/
|
163
|
-
servername
|
164
|
-
status=unixsock(
|
163
|
+
servername = Regexp.last_match[ 1]
|
164
|
+
status = unixsock('show stat')
|
165
165
|
status.each do |line|
|
166
166
|
data = line.split(',')
|
167
|
-
if
|
167
|
+
if ( data[1] == servername) && ( data[17] =~ /Down|MAINT/i)
|
168
168
|
unixsock("enable server #{data[0]}/#{servername}")
|
169
169
|
end
|
170
170
|
end
|
data/lib/haproxyctl.rb
CHANGED
@@ -6,14 +6,14 @@ module HAProxyCTL
|
|
6
6
|
include Environment
|
7
7
|
|
8
8
|
def start
|
9
|
-
puts
|
9
|
+
puts 'starting haproxy...'
|
10
10
|
system("#{exec} -f #{config_path} -D -p #{pidfile}")
|
11
|
-
newpid = check_running
|
12
|
-
if
|
11
|
+
newpid = check_running
|
12
|
+
if newpid =~ /^\d+$/
|
13
13
|
puts "haproxy is running on pid #{newpid}"
|
14
14
|
return true
|
15
15
|
else
|
16
|
-
puts
|
16
|
+
puts 'error. haproxy did not start!'
|
17
17
|
return nil
|
18
18
|
end
|
19
19
|
end
|
@@ -22,39 +22,38 @@ module HAProxyCTL
|
|
22
22
|
if pid
|
23
23
|
puts "stopping haproxy on pid #{pid}..."
|
24
24
|
system("kill #{pid}") || system("kill -9 #{pid}")
|
25
|
-
puts
|
25
|
+
puts '... stopped'
|
26
26
|
else
|
27
|
-
puts
|
27
|
+
puts 'haproxy is not running!'
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def reload(pid)
|
32
|
-
if
|
32
|
+
if pid
|
33
33
|
puts "gracefully stopping connections on pid #{pid}..."
|
34
34
|
system("#{exec} -f #{config_path} -sf #{pid}")
|
35
35
|
puts "checking if connections still alive on #{pid}..."
|
36
|
-
nowpid = check_running
|
37
|
-
while
|
36
|
+
nowpid = check_running
|
37
|
+
while pid == nowpid
|
38
38
|
puts "still haven't killed old pid.
|
39
39
|
waiting 2s for existing connections to die...
|
40
40
|
(ctrl+c to stop this check)"
|
41
41
|
sleep 2
|
42
|
-
nowpid = check_running
|
42
|
+
nowpid = check_running || 0
|
43
43
|
end
|
44
44
|
puts "reloaded haproxy on pid #{nowpid}"
|
45
45
|
else
|
46
|
-
puts
|
46
|
+
puts 'haproxy is not running!'
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
def unixsock(command)
|
51
|
-
|
52
|
-
output=[]
|
51
|
+
output = []
|
53
52
|
runs = 0
|
54
|
-
|
55
|
-
begin
|
56
|
-
ctl=UNIXSocket.open(socket)
|
57
|
-
if
|
53
|
+
|
54
|
+
begin
|
55
|
+
ctl = UNIXSocket.open(socket)
|
56
|
+
if ctl
|
58
57
|
ctl.write "#{command}\r\n"
|
59
58
|
else
|
60
59
|
puts "cannot talk to #{socket}"
|
@@ -63,21 +62,21 @@ module HAProxyCTL
|
|
63
62
|
ctl.close
|
64
63
|
sleep 0.5
|
65
64
|
runs += 1
|
66
|
-
if
|
65
|
+
if runs < 4
|
67
66
|
retry
|
68
67
|
else
|
69
68
|
puts "the unix socket at #{socket} closed before we could complete this request"
|
70
69
|
exit
|
71
70
|
end
|
72
71
|
end
|
73
|
-
while (line = ctl.gets)
|
74
|
-
unless
|
72
|
+
while (line = ctl.gets)
|
73
|
+
unless line =~ /Unknown command/
|
75
74
|
output << line
|
76
75
|
end
|
77
76
|
end
|
78
77
|
ctl.close
|
79
78
|
|
80
|
-
|
79
|
+
output
|
81
80
|
end
|
82
81
|
|
83
82
|
def display_usage!
|
@@ -87,7 +86,7 @@ module HAProxyCTL
|
|
87
86
|
|
88
87
|
def usage
|
89
88
|
<<-USAGE
|
90
|
-
usage: #{$
|
89
|
+
usage: #{$PROGRAM_NAME} <argument>
|
91
90
|
where <argument> can be:
|
92
91
|
start : start haproxy unless it is already running
|
93
92
|
stop : stop an existing haproxy
|
@@ -33,25 +33,25 @@ module HAProxyCTL
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
(@exec)
|
37
37
|
end
|
38
38
|
|
39
39
|
def socket
|
40
40
|
@socket ||= begin
|
41
41
|
config.match /stats\s+socket \s*([^\s]*)/
|
42
|
-
|
42
|
+
Regexp.last_match[1] || fail("Expecting 'stats socket <UNIX_socket_path>' in #{config_path}")
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def pidfile
|
47
47
|
if config.match(/pidfile \s*([^\s]*)/)
|
48
|
-
@pidfile =
|
48
|
+
@pidfile = Regexp.last_match[1]
|
49
49
|
else
|
50
|
-
std_pid =
|
50
|
+
std_pid = '/var/run/haproxy.pid'
|
51
51
|
if File.exists?(std_pid)
|
52
52
|
@pidfile = std_pid
|
53
53
|
else
|
54
|
-
|
54
|
+
fail("Expecting 'pidfile <pid_file_path>' in #{config_path} or a pid file in #{std_pid}")
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -68,6 +68,6 @@ module HAProxyCTL
|
|
68
68
|
return pid
|
69
69
|
end
|
70
70
|
end
|
71
|
-
|
71
|
+
alias_method :pidof, :check_running
|
72
72
|
end
|
73
73
|
end
|
data/lib/haproxyctl/version.rb
CHANGED
data/rhapr/Rakefile
CHANGED
@@ -12,12 +12,12 @@ module Rhapr
|
|
12
12
|
@config_path = ENV['HAPROXY_CONFIG']
|
13
13
|
else
|
14
14
|
config_paths = %w{/etc/haproxy/haproxy.cfg /etc/haproxy.cfg /usr/local/etc/haproxy.cfg}
|
15
|
-
config_paths.select!{|cfg| File.exists?(cfg)}
|
15
|
+
config_paths.select! { |cfg| File.exists?(cfg) }
|
16
16
|
|
17
17
|
@config_path = config_paths.first
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
(@config_path)
|
21
21
|
end
|
22
22
|
|
23
23
|
# @return [String] The raw contents of the HAProxy configuration file.
|
@@ -52,7 +52,7 @@ module Rhapr
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
(@exec)
|
56
56
|
end
|
57
57
|
|
58
58
|
# @return [UNIXSocket] A connection to the HAProxy Socket
|
@@ -71,7 +71,7 @@ module Rhapr
|
|
71
71
|
def socket_path
|
72
72
|
@socket_path ||= begin
|
73
73
|
config.match /stats\s+socket\s+([^\s]*)/
|
74
|
-
|
74
|
+
Regexp.last_match[1] || fail(RuntimeError.new "Expecting 'stats socket <UNIX_socket_path>' in #{config_path}")
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -81,7 +81,7 @@ module Rhapr
|
|
81
81
|
def pid
|
82
82
|
@pid ||= begin
|
83
83
|
config.match /pidfile ([^\s]*)/
|
84
|
-
|
84
|
+
Regexp.last_match[1] || '/var/run/haproxy.pid'
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -94,6 +94,6 @@ module Rhapr
|
|
94
94
|
|
95
95
|
return pidof unless pidof.empty?
|
96
96
|
end
|
97
|
-
|
97
|
+
alias_method :pidof, :check_running
|
98
98
|
end
|
99
99
|
end
|
@@ -21,7 +21,7 @@ module Rhapr
|
|
21
21
|
resp = send 'clear counters'
|
22
22
|
resp == EMPTY
|
23
23
|
end
|
24
|
-
|
24
|
+
alias_method :clear, :clear_counters
|
25
25
|
|
26
26
|
# @return [Hash{String => String}] The 'show info' attributes, from HAProxy, parsed into a Hash.
|
27
27
|
def show_info
|
@@ -29,38 +29,38 @@ module Rhapr
|
|
29
29
|
|
30
30
|
attrs = resp.split("\n")
|
31
31
|
|
32
|
-
attrs.map!
|
32
|
+
attrs.map! do|line|
|
33
33
|
_attr, *_val = line.split(/: /)
|
34
|
-
[
|
35
|
-
|
34
|
+
[_attr, _val.join]
|
35
|
+
end
|
36
36
|
|
37
|
-
Hash[ attrs
|
37
|
+
Hash[ attrs]
|
38
38
|
end
|
39
|
-
|
39
|
+
alias_method :info, :show_info
|
40
40
|
|
41
41
|
# @return [Array<Hash{String => String}>] The 'show stat' response, from HAProxy, parsed into an Array of Hashes.
|
42
42
|
def show_stat
|
43
43
|
resp = send 'show stat'
|
44
44
|
resp.gsub!(/^# /, '')
|
45
45
|
|
46
|
-
csv = CSV.parse(resp, :
|
46
|
+
csv = CSV.parse(resp, headers: true)
|
47
47
|
out = csv.map(&:to_a)
|
48
48
|
|
49
|
-
out.map!{|row| Hash[ row
|
49
|
+
out.map! { |row| Hash[ row] }
|
50
50
|
|
51
|
-
|
51
|
+
(out)
|
52
52
|
end
|
53
|
-
|
53
|
+
alias_method :stat, :show_stat
|
54
54
|
|
55
55
|
# @todo: Implement. I do not know the possible errors that may be present, nor how HAProxy will render them.
|
56
56
|
def show_errors
|
57
57
|
end
|
58
|
-
|
58
|
+
alias_method :errors, :show_errors
|
59
59
|
|
60
60
|
# @todo: Implement. Not sure how this should look. It's likely that I will want to 'interpret' the data that is spit out.
|
61
61
|
def show_sess(id)
|
62
62
|
end
|
63
|
-
|
63
|
+
alias_method :session, :show_sess
|
64
64
|
|
65
65
|
# @return [Array<Fixnum, Fixnum>] An Array with Two Elements: the Current Weight and the Initial Weight.
|
66
66
|
# @todo: Allow the numeric id to be used as a parameter?
|
@@ -68,11 +68,11 @@ module Rhapr
|
|
68
68
|
resp = send "get weight #{backend}/#{server}"
|
69
69
|
|
70
70
|
resp.match /([[:digit:]]+) \(initial ([[:digit:]]+)\)/
|
71
|
-
weight, initial =
|
71
|
+
weight, initial = Regexp.last_match[1], Regexp.last_match[2]
|
72
72
|
|
73
73
|
return [weight.to_i, initial.to_i] if weight and initial
|
74
74
|
|
75
|
-
|
75
|
+
fail ArgumentError.new("HAProxy did not recognize the specified Backend/Server. Response from HAProxy: #{resp}")
|
76
76
|
end
|
77
77
|
|
78
78
|
# @todo: Implement.
|
@@ -88,7 +88,7 @@ module Rhapr
|
|
88
88
|
def enable(backend, server)
|
89
89
|
end
|
90
90
|
|
91
|
-
|
91
|
+
protected
|
92
92
|
# @param [UNIXSocket]
|
93
93
|
# @param [String]
|
94
94
|
# @return [nil]
|
@@ -105,7 +105,7 @@ module Rhapr
|
|
105
105
|
# @see Rhapr::Interface#read
|
106
106
|
def read_full(socket)
|
107
107
|
output = []
|
108
|
-
output << read(socket) until
|
108
|
+
output << read(socket) until sock.eof?
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
data/rhapr/rhapr.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
3
|
require 'rhapr/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
@@ -17,6 +17,6 @@ Gem::Specification.new do |s|
|
|
17
17
|
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
21
21
|
s.require_paths = ['lib']
|
22
22
|
end
|
data/rhapr/spec/quality_spec.rb
CHANGED
@@ -4,7 +4,7 @@ IGNORE = /\.(gitmodules|png$|tar$|gz$|rbc$|gem$|pdf$)/
|
|
4
4
|
|
5
5
|
describe 'The application itself' do
|
6
6
|
it 'has no malformed whitespace' do
|
7
|
-
files = `git ls-files`.split("\n").select {|fn| fn !~ IGNORE}
|
7
|
+
files = `git ls-files`.split("\n").select { |fn| fn !~ IGNORE }
|
8
8
|
|
9
9
|
files.should be_well_formed
|
10
10
|
end
|
@@ -49,9 +49,9 @@ describe Rhapr::Environment do
|
|
49
49
|
it 'should raise an exception if it cannot read from #config_path' do
|
50
50
|
File.should_receive(:read).and_raise(Errno::ENOENT)
|
51
51
|
|
52
|
-
lambda
|
52
|
+
lambda do
|
53
53
|
@env_test.config
|
54
|
-
|
54
|
+
end.should raise_error(RuntimeError)
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'should read and return the contents of a file' do
|
@@ -106,9 +106,9 @@ describe Rhapr::Environment do
|
|
106
106
|
it 'should raise an error if it cannot derive an io socket from the config file' do
|
107
107
|
@env_test.should_receive(:config).and_return { config_for(:crappy_haproxy) }
|
108
108
|
|
109
|
-
lambda
|
109
|
+
lambda do
|
110
110
|
@env_test.socket_path
|
111
|
-
|
111
|
+
end.should raise_error(RuntimeError)
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Rhapr::Interface do
|
4
|
-
let(:basic_info)
|
4
|
+
let(:basic_info) do
|
5
5
|
"Name: HAProxy\nVersion: 1.4.15\nRelease_date: 2011/04/08\nNbproc: 1\nProcess_num: 1\nPid: 97413\nUptime: 0d 18h43m53s\n" <<
|
6
6
|
"Uptime_sec: 67433\nMemmax_MB: 0\nUlimit-n: 2066\nMaxsock: 2066\nMaxconn: 1024\nMaxpipes: 0\nCurrConns: 1\nPipesUsed: 0\n" <<
|
7
7
|
"PipesFree: 0\nTasks: 7\nRun_queue: 1\nnode: skg.local\ndescription: \n"
|
8
|
-
|
8
|
+
end
|
9
9
|
|
10
|
-
let(:basic_stat)
|
11
|
-
|
12
|
-
|
10
|
+
let(:basic_stat) do
|
11
|
+
'# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,' <<
|
12
|
+
'chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,' <<
|
13
13
|
"hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,\nsrv,FRONTEND," <<
|
14
14
|
",,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,0,,,,,,,,,,,0,0,0,,,\nsrv,srv1,0,0,0,0,20,0,0,0,,0,,0,0,0,0,DOWN,1,1,0," <<
|
15
15
|
"0,1,72468,72468,,1,1,1,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,\nsrv,srv2,0,0,0,0,20,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,72465,72465,," <<
|
16
16
|
"1,1,2,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,\n"
|
17
|
-
|
18
|
-
|
17
|
+
end
|
19
18
|
|
20
19
|
subject { Rhapr::Interface.new }
|
21
20
|
|
@@ -46,7 +45,7 @@ describe Rhapr::Interface do
|
|
46
45
|
stats = subject.show_stat
|
47
46
|
|
48
47
|
stats.should be_a(Array)
|
49
|
-
stats.each{|stat| stat.should be_a(Hash) }
|
48
|
+
stats.each { |stat| stat.should be_a(Hash) }
|
50
49
|
end
|
51
50
|
|
52
51
|
it 'should strip the "# " from the beginning of the headers, before calling CSV.parse' do
|
@@ -70,9 +69,9 @@ describe Rhapr::Interface do
|
|
70
69
|
it 'should raise an error if the specific backend+server is not known to HAProxy' do
|
71
70
|
subject.should_receive(:send).with('get weight test/test9').and_return('No such server.')
|
72
71
|
|
73
|
-
lambda
|
72
|
+
lambda do
|
74
73
|
subject.get_weight('test', 'test9')
|
75
|
-
|
74
|
+
end.should raise_error(ArgumentError, 'HAProxy did not recognize the specified Backend/Server. Response from HAProxy: No such server.')
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
data/rhapr/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,7 @@ require 'bundler/setup'
|
|
3
3
|
Bundler.require :default
|
4
4
|
Bundler.require :development
|
5
5
|
|
6
|
-
Dir[ Bundler.root.join('spec/support/**/*.rb')
|
6
|
+
Dir[ Bundler.root.join('spec/support/**/*.rb')].each { |f| require f }
|
7
7
|
|
8
8
|
RSpec.configure do |c|
|
9
9
|
c.include CustomMatchers
|
@@ -8,7 +8,7 @@ module ConfigFixtures
|
|
8
8
|
def fixture_for(sym)
|
9
9
|
config_fixtures[sym][:fixture]
|
10
10
|
end
|
11
|
-
|
11
|
+
alias_method :config_for, :fixture_for
|
12
12
|
|
13
13
|
def path_for(sym)
|
14
14
|
config_fixtures[sym][:path]
|
@@ -17,20 +17,20 @@ module ConfigFixtures
|
|
17
17
|
# @see ConfigFixtures#create_fixture_hash
|
18
18
|
def config_fixtures
|
19
19
|
@config_fixtures ||= begin
|
20
|
-
hash = Hash.new {|k,v| k[v] = {}}
|
20
|
+
hash = Hash.new { |k, v| k[v] = {} }
|
21
21
|
hash.merge!(create_fixture_hash)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
# @return [Hash{Symbol => String}]
|
26
26
|
def create_fixture_hash
|
27
|
-
Hash[ find_fixtures.map{|fpath| map_fixture(fpath) }
|
27
|
+
Hash[ find_fixtures.map { |fpath| map_fixture(fpath) }]
|
28
28
|
end
|
29
29
|
|
30
30
|
# @param [String]
|
31
31
|
# @return [Array<Symbol, String>]
|
32
32
|
def map_fixture(fpath)
|
33
|
-
[symbolize_filename(fpath), {:
|
33
|
+
[symbolize_filename(fpath), { path: fpath, fixture: read_file(fpath) }]
|
34
34
|
end
|
35
35
|
|
36
36
|
# @return [Array<String>]
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module CustomMatchers
|
2
2
|
class BeWellFormed
|
3
3
|
def matches?(files)
|
4
|
-
@errors = files.map
|
4
|
+
@errors = files.map do|filename|
|
5
5
|
[
|
6
6
|
check_for_tabs(filename),
|
7
7
|
excessive_spacing(filename),
|
8
8
|
newline_precedes_eof(filename)
|
9
9
|
]
|
10
|
-
|
10
|
+
end.flatten.compact
|
11
11
|
|
12
12
|
@errors.empty?
|
13
13
|
end
|
@@ -16,7 +16,7 @@ module CustomMatchers
|
|
16
16
|
@errors.join("\n")
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
private
|
20
20
|
def check_for_tabs(filename)
|
21
21
|
bad_lines = File.readlines(filename).each_with_index.map do |line, line_no|
|
22
22
|
line_no + 1 if line["\t"] and line !~ /^\s+#.*\s+\n$/
|
data/rubocop-todo.yml
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2014-02-04 10:23:58 +0100 using RuboCop version 0.18.1.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offences are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offence count: 3
|
9
|
+
AmbiguousRegexpLiteral:
|
10
|
+
Enabled: false
|
11
|
+
|
12
|
+
# Offence count: 3
|
13
|
+
# Cop supports --auto-correct.
|
14
|
+
AndOr:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
# Offence count: 3
|
18
|
+
BlockAlignment:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
# Offence count: 8
|
22
|
+
BlockNesting:
|
23
|
+
Max: 4
|
24
|
+
|
25
|
+
# Offence count: 10
|
26
|
+
Documentation:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
# Offence count: 1
|
30
|
+
EmptyLinesAroundAccessModifier:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
# Offence count: 2
|
34
|
+
IfUnlessModifier:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
# Offence count: 80
|
38
|
+
LineLength:
|
39
|
+
Max: 152
|
40
|
+
|
41
|
+
# Offence count: 5
|
42
|
+
# Configuration parameters: CountComments.
|
43
|
+
MethodLength:
|
44
|
+
Max: 32
|
45
|
+
|
46
|
+
# Offence count: 2
|
47
|
+
ParenthesesAsGroupedExpression:
|
48
|
+
Enabled: false
|
49
|
+
|
50
|
+
# Offence count: 2
|
51
|
+
# Configuration parameters: NamePrefixBlacklist.
|
52
|
+
PredicateName:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
# Offence count: 3
|
56
|
+
# Configuration parameters: SupportedStyles.
|
57
|
+
RaiseArgs:
|
58
|
+
EnforcedStyle: compact
|
59
|
+
|
60
|
+
# Offence count: 1
|
61
|
+
RedundantBegin:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
# Offence count: 2
|
65
|
+
Syntax:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
# Offence count: 2
|
69
|
+
UselessAssignment:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
# Offence count: 2
|
73
|
+
Void:
|
74
|
+
Enabled: false
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haproxyctl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: This is a simple wrapper to make life with HAProxy a little more convenient.
|
15
15
|
Acts as an init script for start, stop, reload, restart, etc. Leverages 'socket'
|
@@ -24,6 +24,7 @@ extensions: []
|
|
24
24
|
extra_rdoc_files: []
|
25
25
|
files:
|
26
26
|
- .gitignore
|
27
|
+
- .rubocop.yml
|
27
28
|
- Gemfile
|
28
29
|
- LICENSE
|
29
30
|
- README.md
|
@@ -53,6 +54,7 @@ files:
|
|
53
54
|
- rhapr/spec/spec_helper.rb
|
54
55
|
- rhapr/spec/support/config_fixtures.rb
|
55
56
|
- rhapr/spec/support/custom_matchers.rb
|
57
|
+
- rubocop-todo.yml
|
56
58
|
homepage: https://github.com/flores/haproxyctl
|
57
59
|
licenses:
|
58
60
|
- MIT
|