serverdensity-heroku 0.0.3
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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +1 -0
- data/bin/LICENSE +27 -0
- data/bin/LICENSE-minjson +504 -0
- data/bin/agent-heroku-test.py +2 -0
- data/bin/agent.py +503 -0
- data/bin/checks.py +2497 -0
- data/bin/checks.pyc +0 -0
- data/bin/config.cfg +56 -0
- data/bin/daemon.py +174 -0
- data/bin/daemon.pyc +0 -0
- data/bin/minjson.py +280 -0
- data/bin/plugins.py +315 -0
- data/bin/sd-agent-pkg.init +85 -0
- data/bin/sd-agent.init +73 -0
- data/bin/sd-deploy.py +317 -0
- data/lib/serverdensity-heroku/version.rb +5 -0
- data/lib/serverdensity-heroku.rb +10 -0
- data/serverdensity-heroku.gemspec +19 -0
- metadata +82 -0
data/bin/sd-deploy.py
ADDED
@@ -0,0 +1,317 @@
|
|
1
|
+
'''
|
2
|
+
Server Density
|
3
|
+
www.serverdensity.com
|
4
|
+
----
|
5
|
+
Server monitoring agent for Linux, FreeBSD and Mac OS X
|
6
|
+
|
7
|
+
Licensed under Simplified BSD License (see LICENSE)
|
8
|
+
'''
|
9
|
+
|
10
|
+
#
|
11
|
+
# Why are you using this?
|
12
|
+
#
|
13
|
+
import time
|
14
|
+
print 'Note: This script is for automating deployments and is not the normal way to install the SD agent. See http://www.serverdensity.com/docs/agent/installation/'
|
15
|
+
print 'Continuing in 4 seconds...'
|
16
|
+
time.sleep(4)
|
17
|
+
|
18
|
+
#
|
19
|
+
# Argument checks
|
20
|
+
#
|
21
|
+
import sys
|
22
|
+
|
23
|
+
if len(sys.argv) < 5:
|
24
|
+
print 'Usage: python sd-deploy.py [API URL] [SD URL] [username] [password] [[init]]'
|
25
|
+
sys.exit(2)
|
26
|
+
|
27
|
+
#
|
28
|
+
# Get server details
|
29
|
+
#
|
30
|
+
|
31
|
+
import socket
|
32
|
+
|
33
|
+
# IP
|
34
|
+
try:
|
35
|
+
serverIp = socket.gethostbyname(socket.gethostname())
|
36
|
+
|
37
|
+
except socket.error, e:
|
38
|
+
print 'Unable to get server IP: ' + str(e)
|
39
|
+
sys.exit(2)
|
40
|
+
|
41
|
+
# Hostname
|
42
|
+
try:
|
43
|
+
serverHostname = hostname = socket.getfqdn()
|
44
|
+
|
45
|
+
except socket.error, e:
|
46
|
+
print 'Unable to get server hostname: ' + str(e)
|
47
|
+
sys.exit(2)
|
48
|
+
|
49
|
+
#
|
50
|
+
# Get latest agent version
|
51
|
+
#
|
52
|
+
|
53
|
+
print '1/4: Downloading latest agent version';
|
54
|
+
|
55
|
+
import httplib
|
56
|
+
import urllib2
|
57
|
+
|
58
|
+
# Request details
|
59
|
+
try:
|
60
|
+
requestAgent = urllib2.urlopen('http://www.serverdensity.com/agentupdate/')
|
61
|
+
responseAgent = requestAgent.read()
|
62
|
+
|
63
|
+
except urllib2.HTTPError, e:
|
64
|
+
print 'Unable to get latest version info - HTTPError = ' + str(e)
|
65
|
+
sys.exit(2)
|
66
|
+
|
67
|
+
except urllib2.URLError, e:
|
68
|
+
print 'Unable to get latest version info - URLError = ' + str(e)
|
69
|
+
sys.exit(2)
|
70
|
+
|
71
|
+
except httplib.HTTPException, e:
|
72
|
+
print 'Unable to get latest version info - HTTPException'
|
73
|
+
sys.exit(2)
|
74
|
+
|
75
|
+
except Exception, e:
|
76
|
+
import traceback
|
77
|
+
print 'Unable to get latest version info - Exception = ' + traceback.format_exc()
|
78
|
+
sys.exit(2)
|
79
|
+
|
80
|
+
#
|
81
|
+
# Define downloader function
|
82
|
+
#
|
83
|
+
|
84
|
+
import md5 # I know this is depreciated, but we still support Python 2.4 and hashlib is only in 2.5. Case 26918
|
85
|
+
import urllib
|
86
|
+
|
87
|
+
def downloadFile(agentFile, recursed = False):
|
88
|
+
print 'Downloading ' + agentFile['name']
|
89
|
+
|
90
|
+
downloadedFile = urllib.urlretrieve('http://www.serverdensity.com/downloads/sd-agent/' + agentFile['name'])
|
91
|
+
|
92
|
+
# Do md5 check to make sure the file downloaded properly
|
93
|
+
checksum = md5.new()
|
94
|
+
f = file(downloadedFile[0], 'rb')
|
95
|
+
|
96
|
+
# Although the files are small, we can't guarantee the available memory nor that there
|
97
|
+
# won't be large files in the future, so read the file in small parts (1kb at time)
|
98
|
+
while True:
|
99
|
+
part = f.read(1024)
|
100
|
+
|
101
|
+
if not part:
|
102
|
+
break # end of file
|
103
|
+
|
104
|
+
checksum.update(part)
|
105
|
+
|
106
|
+
f.close()
|
107
|
+
|
108
|
+
# Do we have a match?
|
109
|
+
if checksum.hexdigest() == agentFile['md5']:
|
110
|
+
return downloadedFile[0]
|
111
|
+
|
112
|
+
else:
|
113
|
+
# Try once more
|
114
|
+
if recursed == False:
|
115
|
+
downloadFile(agentFile, True)
|
116
|
+
|
117
|
+
else:
|
118
|
+
print agentFile['name'] + ' did not match its checksum - it is corrupted. This may be caused by network issues so please try again in a moment.'
|
119
|
+
sys.exit(2)
|
120
|
+
|
121
|
+
#
|
122
|
+
# Install the agent files
|
123
|
+
#
|
124
|
+
|
125
|
+
# We need to return the data using JSON. As of Python 2.6+, there is a core JSON
|
126
|
+
# module. We have a 2.4/2.5 compatible lib included with the agent but if we're
|
127
|
+
# on 2.6 or above, we should use the core module which will be faster
|
128
|
+
import platform
|
129
|
+
|
130
|
+
pythonVersion = platform.python_version_tuple()
|
131
|
+
|
132
|
+
# Decode the JSON
|
133
|
+
if int(pythonVersion[1]) >= 6: # Don't bother checking major version since we only support v2 anyway
|
134
|
+
import json
|
135
|
+
|
136
|
+
try:
|
137
|
+
updateInfo = json.loads(responseAgent)
|
138
|
+
except Exception, e:
|
139
|
+
print 'Unable to get latest version info. Try again later.'
|
140
|
+
sys.exit(2)
|
141
|
+
|
142
|
+
else:
|
143
|
+
import minjson
|
144
|
+
|
145
|
+
try:
|
146
|
+
updateInfo = minjson.safeRead(responseAgent)
|
147
|
+
except Exception, e:
|
148
|
+
print 'Unable to get latest version info. Try again later.'
|
149
|
+
sys.exit(2)
|
150
|
+
|
151
|
+
# Loop through the new files and call the download function
|
152
|
+
for agentFile in updateInfo['files']:
|
153
|
+
agentFile['tempFile'] = downloadFile(agentFile)
|
154
|
+
|
155
|
+
# If we got to here then everything worked out fine. However, all the files are still in temporary locations so we need to move them
|
156
|
+
import os
|
157
|
+
import shutil # Prevents [Errno 18] Invalid cross-device link (case 26878) - http://mail.python.org/pipermail/python-list/2005-February/308026.html
|
158
|
+
|
159
|
+
# Make sure doesn't exist already
|
160
|
+
if os.path.exists('sd-agent/'):
|
161
|
+
shutil.rmtree('sd-agent/')
|
162
|
+
|
163
|
+
os.mkdir('sd-agent')
|
164
|
+
|
165
|
+
for agentFile in updateInfo['files']:
|
166
|
+
print 'Installing ' + agentFile['name']
|
167
|
+
|
168
|
+
if agentFile['name'] != 'config.cfg':
|
169
|
+
shutil.move(agentFile['tempFile'], 'sd-agent/' + agentFile['name'])
|
170
|
+
|
171
|
+
print 'Agent files downloaded'
|
172
|
+
|
173
|
+
#
|
174
|
+
# Call API to add new server
|
175
|
+
#
|
176
|
+
|
177
|
+
print '2/4: Adding new server'
|
178
|
+
|
179
|
+
# Build API payload
|
180
|
+
import time
|
181
|
+
timestamp = time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime())
|
182
|
+
|
183
|
+
postData = urllib.urlencode({'name' : serverHostname, 'ip' : serverIp, 'notes' : 'Added by sd-deploy: ' + timestamp })
|
184
|
+
|
185
|
+
# Send request
|
186
|
+
try:
|
187
|
+
# Password manager
|
188
|
+
mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
189
|
+
mgr.add_password(None, sys.argv[1] + '/1.0/', sys.argv[3], sys.argv[4])
|
190
|
+
opener = urllib2.build_opener(urllib2.HTTPBasicAuthHandler(mgr), urllib2.HTTPDigestAuthHandler(mgr))
|
191
|
+
|
192
|
+
urllib2.install_opener(opener)
|
193
|
+
|
194
|
+
# Build the request handler
|
195
|
+
requestAdd = urllib2.Request(sys.argv[1] + '/1.0/?account=' + sys.argv[2] + '&c=servers/add', postData, { 'User-Agent' : 'Server Density Deploy' })
|
196
|
+
|
197
|
+
# Do the request, log any errors
|
198
|
+
responseAdd = urllib2.urlopen(requestAdd)
|
199
|
+
|
200
|
+
readAdd = responseAdd.read()
|
201
|
+
|
202
|
+
except urllib2.HTTPError, e:
|
203
|
+
print 'HTTPError = ' + str(e)
|
204
|
+
|
205
|
+
if os.path.exists('sd-agent/'):
|
206
|
+
shutil.rmtree('sd-agent/')
|
207
|
+
|
208
|
+
except urllib2.URLError, e:
|
209
|
+
print 'URLError = ' + str(e)
|
210
|
+
|
211
|
+
if os.path.exists('sd-agent/'):
|
212
|
+
shutil.rmtree('sd-agent/')
|
213
|
+
|
214
|
+
except httplib.HTTPException, e: # Added for case #26701
|
215
|
+
print 'HTTPException' + str(e)
|
216
|
+
|
217
|
+
if os.path.exists('sd-agent/'):
|
218
|
+
shutil.rmtree('sd-agent/')
|
219
|
+
|
220
|
+
except Exception, e:
|
221
|
+
import traceback
|
222
|
+
print 'Exception = ' + traceback.format_exc()
|
223
|
+
|
224
|
+
if os.path.exists('sd-agent/'):
|
225
|
+
shutil.rmtree('sd-agent/')
|
226
|
+
|
227
|
+
# Decode the JSON
|
228
|
+
if int(pythonVersion[1]) >= 6: # Don't bother checking major version since we only support v2 anyway
|
229
|
+
import json
|
230
|
+
|
231
|
+
try:
|
232
|
+
serverInfo = json.loads(readAdd)
|
233
|
+
except Exception, e:
|
234
|
+
print 'Unable to add server.'
|
235
|
+
|
236
|
+
if os.path.exists('sd-agent/'):
|
237
|
+
shutil.rmtree('sd-agent/')
|
238
|
+
|
239
|
+
sys.exit(2)
|
240
|
+
|
241
|
+
else:
|
242
|
+
import minjson
|
243
|
+
|
244
|
+
try:
|
245
|
+
serverInfo = minjson.safeRead(readAdd)
|
246
|
+
except Exception, e:
|
247
|
+
print 'Unable to add server.'
|
248
|
+
|
249
|
+
if os.path.exists('sd-agent/'):
|
250
|
+
shutil.rmtree('sd-agent/')
|
251
|
+
|
252
|
+
sys.exit(2)
|
253
|
+
|
254
|
+
print 'Server added - ID: ' + str(serverInfo['data']['serverId'])
|
255
|
+
|
256
|
+
#
|
257
|
+
# Write config file
|
258
|
+
#
|
259
|
+
|
260
|
+
print '3/4: Writing config file'
|
261
|
+
|
262
|
+
configCfg = '[Main]\nsd_url: http://' + sys.argv[2] + '\nagent_key: ' + serverInfo['data']['agentKey'] + '\napache_status_url: http://www.example.com/server-status/?auto'
|
263
|
+
|
264
|
+
try:
|
265
|
+
f = open('sd-agent/config.cfg', 'w')
|
266
|
+
f.write(configCfg)
|
267
|
+
f.close()
|
268
|
+
|
269
|
+
except Exception, e:
|
270
|
+
import traceback
|
271
|
+
print 'Exception = ' + traceback.format_exc()
|
272
|
+
|
273
|
+
if os.path.exists('sd-agent/'):
|
274
|
+
shutil.rmtree('sd-agent/')
|
275
|
+
|
276
|
+
print 'Config file written'
|
277
|
+
|
278
|
+
#
|
279
|
+
# Install init.d
|
280
|
+
#
|
281
|
+
|
282
|
+
if len(sys.argv) == 6:
|
283
|
+
|
284
|
+
print '4/4: Installing init.d script'
|
285
|
+
|
286
|
+
shutil.copy('sd-agent/sd-agent.init', '/etc/init.d/sd-agent')
|
287
|
+
|
288
|
+
import subprocess
|
289
|
+
|
290
|
+
print 'Setting permissions'
|
291
|
+
|
292
|
+
df = subprocess.Popen(['chmod', '0755', '/etc/init.d/sd-agent'], stdout=subprocess.PIPE).communicate()[0]
|
293
|
+
|
294
|
+
print 'chkconfig'
|
295
|
+
|
296
|
+
df = subprocess.Popen(['chkconfig', '--add', 'sd-agent'], stdout=subprocess.PIPE).communicate()[0]
|
297
|
+
|
298
|
+
print 'Setting paths'
|
299
|
+
|
300
|
+
path = os.path.realpath(__file__)
|
301
|
+
path = os.path.dirname(path)
|
302
|
+
|
303
|
+
df = subprocess.Popen(['ln', '-s', path + '/sd-agent/', '/usr/bin/sd-agent'], stdout=subprocess.PIPE).communicate()[0]
|
304
|
+
|
305
|
+
print 'Install completed'
|
306
|
+
|
307
|
+
print 'Launch: /etc/init.d/sd-agent start'
|
308
|
+
|
309
|
+
else:
|
310
|
+
|
311
|
+
print '4/4: Not installing init.d script'
|
312
|
+
print 'Install completed'
|
313
|
+
|
314
|
+
path = os.path.realpath(__file__)
|
315
|
+
path = os.path.dirname(path)
|
316
|
+
|
317
|
+
print 'Launch: python ' + path + '/sd-agent/agent.py start'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "serverdensity-heroku/version"
|
2
|
+
|
3
|
+
module Serverdensity
|
4
|
+
module Heroku
|
5
|
+
filename = File.dirname(__FILE__)
|
6
|
+
filename['lib'] = 'bin'
|
7
|
+
execPath = "python "+filename+"/agent-heroku-test.py start"
|
8
|
+
(pid = fork) ? Process.detach(pid) : exec(execPath)
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'serverdensity-heroku/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "serverdensity-heroku"
|
8
|
+
gem.version = Serverdensity::Heroku::VERSION
|
9
|
+
gem.authors = ["Rob Elkin"]
|
10
|
+
gem.email = ["hello@serverdensity.com"]
|
11
|
+
gem.description = "A gem for running the Server Density agent on heroku"
|
12
|
+
gem.summary = ""
|
13
|
+
gem.homepage = "http://www.serverdensity.com"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: serverdensity-heroku
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rob Elkin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-23 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A gem for running the Server Density agent on heroku
|
15
|
+
email:
|
16
|
+
- hello@serverdensity.com
|
17
|
+
executables:
|
18
|
+
- LICENSE
|
19
|
+
- LICENSE-minjson
|
20
|
+
- agent-heroku-test.py
|
21
|
+
- agent.py
|
22
|
+
- checks.py
|
23
|
+
- checks.pyc
|
24
|
+
- config.cfg
|
25
|
+
- daemon.py
|
26
|
+
- daemon.pyc
|
27
|
+
- minjson.py
|
28
|
+
- plugins.py
|
29
|
+
- sd-agent-pkg.init
|
30
|
+
- sd-agent.init
|
31
|
+
- sd-deploy.py
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- Gemfile
|
37
|
+
- Gemfile.lock
|
38
|
+
- LICENSE.txt
|
39
|
+
- README.md
|
40
|
+
- Rakefile
|
41
|
+
- bin/LICENSE
|
42
|
+
- bin/LICENSE-minjson
|
43
|
+
- bin/agent-heroku-test.py
|
44
|
+
- bin/agent.py
|
45
|
+
- bin/checks.py
|
46
|
+
- bin/checks.pyc
|
47
|
+
- bin/config.cfg
|
48
|
+
- bin/daemon.py
|
49
|
+
- bin/daemon.pyc
|
50
|
+
- bin/minjson.py
|
51
|
+
- bin/plugins.py
|
52
|
+
- bin/sd-agent-pkg.init
|
53
|
+
- bin/sd-agent.init
|
54
|
+
- bin/sd-deploy.py
|
55
|
+
- lib/serverdensity-heroku.rb
|
56
|
+
- lib/serverdensity-heroku/version.rb
|
57
|
+
- serverdensity-heroku.gemspec
|
58
|
+
homepage: http://www.serverdensity.com
|
59
|
+
licenses: []
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.8.24
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: ''
|
82
|
+
test_files: []
|