big_brother 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,6 +2,8 @@ module BigBrother
2
2
  class App < Sinatra::Base
3
3
  register Sinatra::Synchrony
4
4
 
5
+ set :raise_errors, false
6
+
5
7
  get "/" do
6
8
  BigBrother.clusters.map do |name, cluster|
7
9
  "#{cluster}: #{cluster.monitored? ? "running" : "not running"}"
@@ -20,11 +22,22 @@ module BigBrother
20
22
  put "/cluster/:name" do |name|
21
23
  halt 304 if @cluster.monitored?
22
24
  @cluster.start_monitoring!
25
+ [200, "OK"]
23
26
  end
24
27
 
25
28
  delete "/cluster/:name" do |name|
26
29
  halt 304 unless @cluster.monitored?
27
30
  @cluster.stop_monitoring!
31
+ [200, "OK"]
32
+ end
33
+
34
+ error do
35
+ e = request.env['sinatra.error']
36
+
37
+ BigBrother.logger.info "Error: #{e}"
38
+ BigBrother.logger.info e.backtrace.join("\n")
39
+
40
+ 'Application error'
28
41
  end
29
42
  end
30
43
  end
@@ -10,6 +10,7 @@ module BigBrother
10
10
  "BigBrother configuration file", "Default: /etc/big_brother.conf") { |v| options[:big_brother_config] = v }
11
11
  opts.on("-D", "--data-dir=path", String,
12
12
  "BigBrother data directory", "Default: /etc/big_brother") { |v| options[:config_dir] = v }
13
+ opts.on("-v", "--verbose", "Log more verbosely") { options[:verbose] = true }
13
14
 
14
15
  opts.separator ""
15
16
 
@@ -45,11 +46,12 @@ module BigBrother
45
46
  end
46
47
 
47
48
  def start
48
- if !File.exists?(options[:big_brother_config])
49
+ unless File.exists?(options[:big_brother_config])
49
50
  puts "Could not find #{options[:big_brother_config]}. Specify correct location with -c file"
50
51
  exit 1
51
52
  end
52
53
 
54
+ BigBrother.logger.level = BigBrother::Logger::Level::DEBUG if options[:verbose]
53
55
  BigBrother.config_dir = options[:config_dir]
54
56
 
55
57
  Thin::Callbacks.after_connect do
@@ -1,6 +1,6 @@
1
1
  module BigBrother
2
2
  class Cluster
3
- attr_reader :fwmark, :scheduler, :check_interval, :nodes
3
+ attr_reader :fwmark, :scheduler, :check_interval, :nodes, :name
4
4
 
5
5
  def initialize(name, attributes = {})
6
6
  @name = name
@@ -33,6 +33,7 @@ module BigBrother
33
33
  BigBrother.ipvs.stop_cluster(@fwmark)
34
34
 
35
35
  @monitored = false
36
+ @nodes.each(&:invalidate_weight!)
36
37
  end
37
38
 
38
39
  def resume_monitoring!
@@ -1,7 +1,10 @@
1
1
  module BigBrother
2
2
  class HealthFetcher
3
3
  def self.current_health(address, port, path)
4
- response = EventMachine::HttpRequest.new("http://#{address}:#{port}#{path}").get
4
+ url = "http://#{address}:#{port}#{path}"
5
+
6
+ BigBrother.logger.debug("Fetching health from #{url}")
7
+ response = EventMachine::HttpRequest.new(url).get
5
8
  response.response_header.status == 200 ? _parse_health(response) : 0
6
9
  end
7
10
 
@@ -1,5 +1,16 @@
1
1
  module BigBrother
2
2
  class Logger
3
+ module Level
4
+ DEBUG = 0
5
+ INFO = 1
6
+ end
7
+
8
+ attr_accessor :level
9
+
10
+ def initialize
11
+ @level = Level::INFO
12
+ end
13
+
3
14
  def write(message)
4
15
  info(message)
5
16
  end
@@ -7,5 +18,9 @@ module BigBrother
7
18
  def info(message)
8
19
  EM.info(message)
9
20
  end
21
+
22
+ def debug(message)
23
+ EM.debug(message) if level == Level::DEBUG
24
+ end
10
25
  end
11
26
  end
@@ -11,10 +11,15 @@ module BigBrother
11
11
  @weight = nil
12
12
  end
13
13
 
14
+ def invalidate_weight!
15
+ @weight = nil
16
+ end
17
+
14
18
  def monitor(cluster)
15
19
  new_weight = _determine_weight(cluster)
20
+ return unless cluster.monitored?
16
21
  if new_weight != @weight
17
- BigBrother.ipvs.edit_node(cluster.fwmark, address, _determine_weight(cluster))
22
+ BigBrother.ipvs.edit_node(cluster.fwmark, address, new_weight)
18
23
  @weight = new_weight
19
24
  end
20
25
  end
@@ -20,6 +20,7 @@ module BigBrother
20
20
  def self.tick
21
21
  @outstanding_ticks += 1
22
22
  BigBrother.clusters.values.select(&:needs_check?).each do |cluster|
23
+ BigBrother.logger.debug("Monitoring cluster #{cluster.name}")
23
24
  cluster.monitor_nodes
24
25
  end
25
26
  @outstanding_ticks -= 1
@@ -1,3 +1,3 @@
1
1
  module BigBrother
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -57,7 +57,7 @@ module BigBrother
57
57
  put "/cluster/test"
58
58
 
59
59
  last_response.status.should == 200
60
- last_response.body.should == ""
60
+ last_response.body.should == "OK"
61
61
  BigBrother.clusters['test'].should be_monitored
62
62
  end
63
63
 
@@ -86,7 +86,7 @@ module BigBrother
86
86
  put "/cluster/test"
87
87
 
88
88
  last_response.status.should == 200
89
- last_response.body.should == ""
89
+ last_response.body.should == "OK"
90
90
  BigBrother.clusters['test'].should be_monitored
91
91
  @recording_executor.commands.first.should == "ipvsadm --add-service --fwmark-service 100 --scheduler wrr"
92
92
  @recording_executor.commands.should include("ipvsadm --add-server --fwmark-service 100 --real-server 127.0.0.1 --ipip --weight 100")
@@ -102,7 +102,7 @@ module BigBrother
102
102
  delete "/cluster/test"
103
103
 
104
104
  last_response.status.should == 200
105
- last_response.body.should == ""
105
+ last_response.body.should == "OK"
106
106
  BigBrother.clusters['test'].should_not be_monitored
107
107
  end
108
108
 
@@ -123,5 +123,18 @@ module BigBrother
123
123
  last_response.body.should == "Cluster test not found"
124
124
  end
125
125
  end
126
+
127
+ describe "error handling" do
128
+ it "logs exceptions" do
129
+ BigBrother.clusters['test'] = "this is not a cluster"
130
+
131
+ BigBrother.logger.should_receive(:info).with(/^Error:/)
132
+ BigBrother.logger.should_receive(:info).with(/big_brother/)
133
+
134
+ put "/cluster/test"
135
+
136
+ last_response.status.should == 500
137
+ end
138
+ end
126
139
  end
127
140
  end
@@ -28,6 +28,22 @@ describe BigBrother::Cluster do
28
28
  cluster.should_not be_monitored
29
29
  @recording_executor.commands.should include("ipvsadm --delete-service --fwmark-service 100")
30
30
  end
31
+
32
+ it "invalidates recorded weights, so it properly updates after a stop/start" do
33
+ node = Factory.node(:address => '127.0.0.1')
34
+ cluster = Factory.cluster(:fwmark => '100', :nodes => [node])
35
+
36
+ BigBrother::HealthFetcher.stub(:current_health).and_return(10)
37
+
38
+ cluster.start_monitoring!
39
+ cluster.monitor_nodes
40
+
41
+ cluster.stop_monitoring!
42
+ cluster.start_monitoring!
43
+ cluster.monitor_nodes
44
+
45
+ @recording_executor.commands.last.should == "ipvsadm --edit-server --fwmark-service 100 --real-server 127.0.0.1 --ipip --weight 10"
46
+ end
31
47
  end
32
48
 
33
49
  describe "#needs_check?" do
@@ -42,6 +58,9 @@ describe BigBrother::Cluster do
42
58
  describe "#monitor_nodes" do
43
59
  it "marks the cluster as no longer requiring monitoring" do
44
60
  cluster = Factory.cluster
61
+
62
+ BigBrother::HealthFetcher.stub(:current_health).and_return(10)
63
+
45
64
  cluster.start_monitoring!
46
65
  cluster.needs_check?.should be_true
47
66
  cluster.monitor_nodes
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe BigBrother::Logger do
4
+ describe 'level' do
5
+ it "does not log debug at info level" do
6
+ logger = BigBrother::Logger.new
7
+ logger.level = BigBrother::Logger::Level::INFO
8
+
9
+ EM.should_receive(:debug).never
10
+
11
+ logger.debug('hi')
12
+ end
13
+ end
14
+ end
@@ -7,6 +7,8 @@ describe BigBrother::Node do
7
7
  BigBrother::HealthFetcher.stub(:current_health).and_return(56)
8
8
  node = Factory.node(:address => '127.0.0.1')
9
9
  cluster = Factory.cluster(:fwmark => 100, :nodes => [node])
10
+ cluster.start_monitoring!
11
+ @recording_executor.commands.clear
10
12
 
11
13
  node.monitor(cluster)
12
14
 
@@ -17,6 +19,8 @@ describe BigBrother::Node do
17
19
  BigBrother::HealthFetcher.stub(:current_health).and_return(56)
18
20
  node = Factory.node(:address => '127.0.0.1')
19
21
  cluster = Factory.cluster(:fwmark => 100, :nodes => [node])
22
+ cluster.start_monitoring!
23
+ @recording_executor.commands.clear
20
24
 
21
25
  BigBrother::StatusFile.new('up', 'test').create('Up for testing')
22
26
 
@@ -29,6 +33,8 @@ describe BigBrother::Node do
29
33
  BigBrother::HealthFetcher.stub(:current_health).and_return(56)
30
34
  node = Factory.node(:address => '127.0.0.1')
31
35
  cluster = Factory.cluster(:fwmark => 100, :nodes => [node])
36
+ cluster.start_monitoring!
37
+ @recording_executor.commands.clear
32
38
 
33
39
  BigBrother::StatusFile.new('down', 'test').create('Down for testing')
34
40
 
@@ -41,6 +47,8 @@ describe BigBrother::Node do
41
47
  BigBrother::HealthFetcher.stub(:current_health).and_return(56)
42
48
  node = Factory.node(:address => '127.0.0.1')
43
49
  cluster = Factory.cluster(:fwmark => 100, :nodes => [node])
50
+ cluster.start_monitoring!
51
+ @recording_executor.commands.clear
44
52
 
45
53
  node.monitor(cluster)
46
54
  node.monitor(cluster)
@@ -52,6 +60,8 @@ describe BigBrother::Node do
52
60
  BigBrother::HealthFetcher.stub(:current_health).and_return(56)
53
61
  node = Factory.node(:address => '127.0.0.1')
54
62
  cluster = Factory.cluster(:fwmark => 100, :nodes => [node])
63
+ cluster.start_monitoring!
64
+ @recording_executor.commands.clear
55
65
 
56
66
  node.monitor(cluster)
57
67
  node.monitor(cluster)
@@ -63,5 +73,17 @@ describe BigBrother::Node do
63
73
  "ipvsadm --edit-server --fwmark-service 100 --real-server 127.0.0.1 --ipip --weight 41"
64
74
  ]
65
75
  end
76
+
77
+ it "does not update the weight if the cluster is no longer monitored" do
78
+ BigBrother::HealthFetcher.stub(:current_health).and_return(56)
79
+ node = Factory.node(:address => '127.0.0.1')
80
+ cluster = Factory.cluster(:fwmark => 100, :nodes => [node])
81
+ cluster.stop_monitoring!
82
+
83
+ @recording_executor.commands.clear
84
+ node.monitor(cluster)
85
+
86
+ @recording_executor.commands.should == []
87
+ end
66
88
  end
67
89
  end
@@ -6,7 +6,7 @@ class Factory
6
6
  'fwmark' => overrides.fetch(:fwmark, 100),
7
7
  'scheduler' => overrides.fetch(:scheduler, 'wrr'),
8
8
  'check_interval' => overrides.fetch(:check_interval, 1),
9
- 'nodes' => overrides.fetch(:nodes, [])
9
+ 'nodes' => overrides.fetch(:nodes, [Factory.node])
10
10
  }
11
11
  )
12
12
  end
@@ -4,4 +4,7 @@ class NullLogger
4
4
 
5
5
  def info(msg)
6
6
  end
7
+
8
+ def debug(msg)
9
+ end
7
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: big_brother
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-17 00:00:00.000000000 Z
12
+ date: 2012-05-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thin
16
- requirement: &70147105239120 !ruby/object:Gem::Requirement
16
+ requirement: &70211323894240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.3.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70147105239120
24
+ version_requirements: *70211323894240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: async-rack
27
- requirement: &70147105238560 !ruby/object:Gem::Requirement
27
+ requirement: &70211323893680 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.5.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70147105238560
35
+ version_requirements: *70211323893680
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &70147105237960 !ruby/object:Gem::Requirement
38
+ requirement: &70211323893120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70147105237960
46
+ version_requirements: *70211323893120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack-fiber_pool
49
- requirement: &70147105237200 !ruby/object:Gem::Requirement
49
+ requirement: &70211323892400 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0.9'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70147105237200
57
+ version_requirements: *70211323892400
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: eventmachine
60
- requirement: &70147105236460 !ruby/object:Gem::Requirement
60
+ requirement: &70211323891660 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>'
@@ -68,10 +68,10 @@ dependencies:
68
68
  version: 1.0.0.beta.100
69
69
  type: :runtime
70
70
  prerelease: false
71
- version_requirements: *70147105236460
71
+ version_requirements: *70211323891660
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: em-http-request
74
- requirement: &70147105235180 !ruby/object:Gem::Requirement
74
+ requirement: &70211323890380 !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
77
77
  - - ~>
@@ -79,10 +79,10 @@ dependencies:
79
79
  version: '1.0'
80
80
  type: :runtime
81
81
  prerelease: false
82
- version_requirements: *70147105235180
82
+ version_requirements: *70211323890380
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: em-synchrony
85
- requirement: &70147105234240 !ruby/object:Gem::Requirement
85
+ requirement: &70211323889400 !ruby/object:Gem::Requirement
86
86
  none: false
87
87
  requirements:
88
88
  - - ~>
@@ -90,10 +90,10 @@ dependencies:
90
90
  version: '1.0'
91
91
  type: :runtime
92
92
  prerelease: false
93
- version_requirements: *70147105234240
93
+ version_requirements: *70211323889400
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: em-resolv-replace
96
- requirement: &70147105233120 !ruby/object:Gem::Requirement
96
+ requirement: &70211323888420 !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
99
  - - ~>
@@ -101,10 +101,10 @@ dependencies:
101
101
  version: '1.1'
102
102
  type: :runtime
103
103
  prerelease: false
104
- version_requirements: *70147105233120
104
+ version_requirements: *70211323888420
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: em-syslog
107
- requirement: &70147105232280 !ruby/object:Gem::Requirement
107
+ requirement: &70211323887380 !ruby/object:Gem::Requirement
108
108
  none: false
109
109
  requirements:
110
110
  - - ~>
@@ -112,10 +112,10 @@ dependencies:
112
112
  version: 0.0.2
113
113
  type: :runtime
114
114
  prerelease: false
115
- version_requirements: *70147105232280
115
+ version_requirements: *70211323887380
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: rspec
118
- requirement: &70147105231800 !ruby/object:Gem::Requirement
118
+ requirement: &70211323886900 !ruby/object:Gem::Requirement
119
119
  none: false
120
120
  requirements:
121
121
  - - ~>
@@ -123,10 +123,10 @@ dependencies:
123
123
  version: 2.9.0
124
124
  type: :development
125
125
  prerelease: false
126
- version_requirements: *70147105231800
126
+ version_requirements: *70211323886900
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: rack-test
129
- requirement: &70147105231220 !ruby/object:Gem::Requirement
129
+ requirement: &70211323886380 !ruby/object:Gem::Requirement
130
130
  none: false
131
131
  requirements:
132
132
  - - ~>
@@ -134,10 +134,10 @@ dependencies:
134
134
  version: 0.6.1
135
135
  type: :development
136
136
  prerelease: false
137
- version_requirements: *70147105231220
137
+ version_requirements: *70211323886380
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: rake
140
- requirement: &70147105230600 !ruby/object:Gem::Requirement
140
+ requirement: &70211323885760 !ruby/object:Gem::Requirement
141
141
  none: false
142
142
  requirements:
143
143
  - - ! '>='
@@ -145,10 +145,10 @@ dependencies:
145
145
  version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
- version_requirements: *70147105230600
148
+ version_requirements: *70211323885760
149
149
  - !ruby/object:Gem::Dependency
150
150
  name: rake_commit
151
- requirement: &70147105229780 !ruby/object:Gem::Requirement
151
+ requirement: &70211323884900 !ruby/object:Gem::Requirement
152
152
  none: false
153
153
  requirements:
154
154
  - - ~>
@@ -156,10 +156,10 @@ dependencies:
156
156
  version: '0.13'
157
157
  type: :development
158
158
  prerelease: false
159
- version_requirements: *70147105229780
159
+ version_requirements: *70211323884900
160
160
  - !ruby/object:Gem::Dependency
161
161
  name: vagrant
162
- requirement: &70147105229320 !ruby/object:Gem::Requirement
162
+ requirement: &70211323884420 !ruby/object:Gem::Requirement
163
163
  none: false
164
164
  requirements:
165
165
  - - ! '>='
@@ -167,13 +167,12 @@ dependencies:
167
167
  version: '0'
168
168
  type: :development
169
169
  prerelease: false
170
- version_requirements: *70147105229320
170
+ version_requirements: *70211323884420
171
171
  description: IPVS backend supervisor
172
172
  email:
173
173
  - code@getbraintree.com
174
174
  executables:
175
175
  - bigbro
176
- - ocf_big_brother
177
176
  extensions: []
178
177
  extra_rdoc_files: []
179
178
  files:
@@ -187,7 +186,6 @@ files:
187
186
  - Rakefile
188
187
  - big_brother.gemspec
189
188
  - bin/bigbro
190
- - bin/ocf_big_brother
191
189
  - config.ru
192
190
  - lib/big_brother.rb
193
191
  - lib/big_brother/app.rb
@@ -211,6 +209,7 @@ files:
211
209
  - spec/big_brother/configuration_spec.rb
212
210
  - spec/big_brother/health_fetcher_spec.rb
213
211
  - spec/big_brother/ipvs_spec.rb
212
+ - spec/big_brother/logger_spec.rb
214
213
  - spec/big_brother/node_spec.rb
215
214
  - spec/big_brother/shell_executor_spec.rb
216
215
  - spec/big_brother/status_file_spec.rb
@@ -257,6 +256,7 @@ test_files:
257
256
  - spec/big_brother/configuration_spec.rb
258
257
  - spec/big_brother/health_fetcher_spec.rb
259
258
  - spec/big_brother/ipvs_spec.rb
259
+ - spec/big_brother/logger_spec.rb
260
260
  - spec/big_brother/node_spec.rb
261
261
  - spec/big_brother/shell_executor_spec.rb
262
262
  - spec/big_brother/status_file_spec.rb
data/bin/ocf_big_brother DELETED
@@ -1,174 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # Michael Vallaly (Aug '11) Ver 1.0
4
- #
5
- # IPVS Supervisor daemon OCF resource handler script
6
- #
7
-
8
- AWK_BIN="/usr/bin/awk"
9
- CURL_BIN="/usr/bin/curl"
10
- EGREP_BIN="/bin/egrep"
11
-
12
- CURL_TIMEOUT_SEC=5
13
- SUPERVISOR_URL="http://127.0.0.1:9292"
14
-
15
- #######################################################################
16
-
17
- # Pull in OCF functions
18
- . /usr/lib/ocf/resource.d/heartbeat/.ocf-shellfuncs
19
-
20
- #######################################################################
21
-
22
- meta_data() {
23
- cat <<END
24
- <?xml version="1.0"?>
25
- <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
26
- <resource-agent name="Big Brother" version="0.9">
27
- <version>1.0</version>
28
-
29
- <longdesc lang="en">
30
- This is the Big Brother Resource Agent. It enables the management
31
- and monitoring of IPVS via the OCF resource API.
32
- </longdesc>
33
- <shortdesc lang="en">Big Brother resource agent</shortdesc>
34
-
35
- <parameters>
36
- <parameter name="cluster" unique="1" required="1">
37
- <longdesc lang="en">
38
- Cluster Name as defined in the Big Brother Configuration
39
- </longdesc>
40
- <shortdesc lang="en">Cluster Name</shortdesc>
41
- <content type="string" default="" />
42
- </parameter>
43
- </parameters>
44
-
45
- <actions>
46
- <action name="start" timeout="20" />
47
- <action name="stop" timeout="40" />
48
- <action name="monitor" timeout="20" interval="10" depth="0" start-delay="0" />
49
- <action name="reload" timeout="60" />
50
- <action name="migrate_to" timeout="100" />
51
- <action name="migrate_from" timeout="90" />
52
- <action name="meta-data" timeout="5" />
53
- <action name="validate-all" timeout="30" />
54
- </actions>
55
- </resource-agent>
56
- END
57
- }
58
-
59
- #######################################################################
60
-
61
- # don't exit on TERM, to test that lrmd makes sure that we do exit
62
- trap sigterm_handler TERM
63
- sigterm_handler() {
64
- ocf_log info "Attempted to use TERM to bring us down. No such luck."
65
- return
66
- }
67
-
68
- ipvs_cluster_usage() {
69
- cat <<END
70
- usage: $0 {start|stop|monitor|meta-data|validate-all}
71
-
72
- Expects to have a fully populated OCF RA-compliant environment set.
73
- END
74
- }
75
-
76
- ipvs_cluster_start() {
77
-
78
- # Check if the protocol is already running
79
- ipvs_cluster_monitor
80
- if [ $? -eq ${OCF_SUCCESS} ]; then
81
- return ${OCF_SUCCESS}
82
- else
83
- # Start the requested cluster
84
- if [ `$CURL_BIN -m ${CURL_TIMEOUT_SEC} -X PUT -w "%{http_code}" -o /dev/null -s "${SUPERVISOR_URL}/cluster/${OCF_RESKEY_cluster}"` == 200 ]; then
85
- return ${OCF_SUCCESS}
86
- else
87
- return ${OCF_ERR_GENERIC}
88
- fi
89
- fi
90
-
91
- }
92
-
93
- ipvs_cluster_stop() {
94
-
95
- # Check if the protocol is already running
96
- ipvs_cluster_monitor
97
- if [ $? -eq ${OCF_SUCCESS} ]; then
98
- # Stop the requested cluster
99
- if [ `$CURL_BIN -m ${CURL_TIMEOUT_SEC} -X DELETE -w "%{http_code}" -o /dev/null -s "${SUPERVISOR_URL}/cluster/${OCF_RESKEY_cluster}"` == 200 ]; then
100
- return ${OCF_SUCCESS}
101
- else
102
- return ${OCF_ERR_GENERIC}
103
- fi
104
- else
105
- return ${OCF_SUCCESS}
106
- fi
107
-
108
- }
109
-
110
- ipvs_cluster_monitor() {
111
-
112
- local cluster_status
113
- local http_status
114
-
115
- # Check if the IPVS supervisor is running for the cluster
116
- cluster_status=`$CURL_BIN -m ${CURL_TIMEOUT_SEC} -w '\nHTTP_Status: %{http_code}\n' -s "${SUPERVISOR_URL}/cluster/${OCF_RESKEY_cluster}"`
117
- # If curl can't connect then we got bigger issues
118
- if [ $? -ne 0 ]; then
119
- return ${OCF_ERR_PERM};
120
- fi
121
-
122
- # Check for remote HTTP response code
123
- http_status=`echo "${cluster_status}" |${EGREP_BIN} -e "^HTTP_Status: "|$AWK_BIN '{print $2}' |tr -d '[:alpha:][:punct:][:space:]' |head -1`
124
-
125
- # We aren't running if we never get a status code back
126
- if [ "${http_status}x" != "x" ]; then
127
- if [ ${http_status} -eq 200 ]; then
128
- if [ `echo ${cluster_status} |${EGREP_BIN} -e "^Running: "|$AWK_BIN '{print $2}'` == "true" ]; then
129
- return ${OCF_SUCCESS}
130
- fi
131
- fi
132
- fi
133
- return ${OCF_NOT_RUNNING}
134
-
135
- }
136
-
137
- ipvs_cluster_validate_all() {
138
-
139
- # Validate binary dependencies are executable
140
- for req_bin in $AWK_BIN $CURL_BIN $EGREP_BIN; do
141
- if [ ! -x "$req_bin" ]; then
142
- ocf_log debug "Unable to execute (${req_bin})! Aborting.."
143
- return ${OCF_ERR_INSTALLED}
144
- fi
145
- done
146
-
147
- # Check if the IPVS supervisor knows about the cluster
148
- if [ `$CURL_BIN -m ${CURL_TIMEOUT_SEC} -w '\nHTTP_Status: %{http_code}\n' -s "${SUPERVISOR_URL}/cluster/${OCF_RESKEY_cluster}" |${EGREP_BIN} -ce '^HTTP_Status: 200'` -eq 0 ]; then
149
- return ${OCF_ERR_ARGS}
150
- fi
151
-
152
- return ${OCF_SUCCESS}
153
-
154
- }
155
-
156
- case $__OCF_ACTION in
157
- meta-data) meta_data
158
- exit ${OCF_SUCCESS}
159
- ;;
160
- start) ipvs_cluster_start;;
161
- stop) ipvs_cluster_stop;;
162
- monitor) ipvs_cluster_monitor;;
163
- validate-all) ipvs_cluster_validate_all;;
164
- usage|help) ipvs_cluster_usage
165
- exit ${OCF_SUCCESS}
166
- ;;
167
- *) ipvs_cluster_usage
168
- exit ${OCF_ERR_UNIMPLEMENTED}
169
- ;;
170
- esac
171
-
172
- rc=$?
173
- ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
174
- exit $rc