Clean : (Grégory Starck) clean of some getattr code, bis.
[shinken.git] / setup.py
blob66ffe5d01268e9651514a9a955045b9d4203a6f7
1 #!/usr/bin/env python
2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
6 #This file is part of Shinken.
8 #Shinken is free software: you can redistribute it and/or modify
9 #it under the terms of the GNU Affero General Public License as published by
10 #the Free Software Foundation, either version 3 of the License, or
11 #(at your option) any later version.
13 #Shinken is distributed in the hope that it will be useful,
14 #but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 #GNU Affero General Public License for more details.
18 #You should have received a copy of the GNU Affero General Public License
19 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
22 #first verion of this file from Maximilien Bersoult
24 from setuptools import setup, find_packages
25 from glob import glob
26 import os, sys, re
27 import ConfigParser
28 import getopt
29 import re
30 if os.name != 'nt':
31 from pwd import getpwnam
32 from grp import getgrnam
34 #Some global variables
35 install_scripts_path = "/usr/bin" #where to install launch scripts. Beter in PATH ;)
36 root_path = "/" #if the setup.py is call with root, get it
38 #We know that a Python 2.3 or Python3K will fail.
39 #We can say why and quit.
40 import platform
41 python_version = tuple((int(s) for s in platform.python_version_tuple()))
43 ## Make sure people are using Python 2.3 or higher
44 if python_version < (2, 4):
45 print "Shinken require as a minimum Python 2.4.x, sorry"
46 sys.exit(1)
48 if python_version < (3):
49 print "Shinken is not yet compatible with Python3k, sorry"
50 sys.exit(1)
52 def getscripts(path):
53 script = os.path.basename(path)
54 return script
59 #Set the default values for the paths
60 #owners and groups
61 if os.name == 'nt':
62 paths_and_owners = {'var' : {'path' : "c:\\shinken\\var", 'owner' : None, 'group' : None },
63 'etc' : {'path' : "c:\\shinken\\etc", 'owner' : None, 'group' : None},
64 'libexec' : {'path' : "c:\\shinken\\libexec", 'owner' : None, 'group' : None},
66 else:
67 paths_and_owners = {'var' : {'path' : "/var/lib/shinken/", 'owner' : 'shinken', 'group' : 'shinken' },
68 'etc' : {'path' : "/etc/shinken", 'owner' : 'shinken', 'group' : 'shinken'},
69 'libexec' : {'path' : "/usr/lib/shinken/plugins", 'owner' : 'shinken', 'group' : 'shinken'},
74 #The default file must have good values for the directories:
75 #etc, var and where to push scripts that launch the app.
76 def generate_default_shinken_file():
77 global paths_and_owners
78 global install_scripts_path
80 #Read the in file, it's our template
81 f = open("bin/default/shinken.in")
82 buf = f.read()
83 f.close
85 #then generate the new one with good values
86 etc_path = paths_and_owners['etc']['path']
87 var_path = paths_and_owners['var']['path']
88 f = open("bin/default/shinken", "w")
89 buf = buf.replace("$ETC$", etc_path)
90 buf = buf.replace("$VAR$", var_path)
91 buf = buf.replace("$SCRIPTS_BIN$", install_scripts_path)
92 f.write(buf)
93 f.close()
96 def parse_config_file(config_file):
97 global paths_and_owners
99 config = ConfigParser.ConfigParser()
100 config.read(config_file)
101 if config._sections == {}:
102 print "Bad or missing config file : %s " % config_file
103 sys.exit(2)
105 for dir in ['var', 'etc', 'libexec']:
106 paths_and_owners[dir]['path'] = config._sections[dir]['path']
108 #on nt no owner...
109 if os.name != 'nt':
110 paths_and_owners[dir]['owner'] = config._sections[dir]['owner']
111 paths_and_owners[dir]['group'] = config._sections[dir]['group']
114 #I search for the --install-scripts= parameter if present to modify the
115 #default/shinken file
116 for arg in sys.argv:
117 print "Argument", arg
118 if re.search("--install-scripts=", arg):
119 elts = arg.split('=')
120 if len(elts) > 1:
121 install_scripts_path = elts[1]
122 print "Install script path", install_scripts_path
123 if re.search("--root=", arg):
124 elts = arg.split('=')
125 if len(elts) > 1:
126 root_path = elts[1]
127 print "New root path", root_path
130 #Get the paths and ownsers form the parameter file
131 #and the generate the default/shinken file so the init.d
132 #scripts will have the good values for directories
133 parse_config_file('setup_parameters.cfg')
134 generate_default_shinken_file()
136 etc_path = paths_and_owners['etc']['path']
137 var_path = paths_and_owners['var']['path']
138 libexec_path = paths_and_owners['libexec']['path']
140 required_pkgs = []
141 if python_version < (2, 5):
142 required_pkgs.append('pyro<4')
143 else:
144 required_pkgs.append('pyro')
145 if python_version < (2, 6):
146 required_pkgs.append('multiprocessing')
148 setup(
149 name = "Shinken",
150 version = "0.4",
151 packages = find_packages(),
152 package_data = {'':['*.py','modules/*.py','modules/*/*.py']},
153 description = "Shinken is a monitoring tool compatible with Nagios configuration and plugins",
154 long_description=open('README').read(),
155 author = "Gabes Jean",
156 author_email = "naparuba@gmail.com",
157 license = "GNU Affero General Public License",
158 url = "http://www.shinken-monitoring.org",
159 zip_safe=False,
160 classifiers=['Development Status :: 4 - Beta',
161 'Environment :: Console',
162 'Intended Audience :: System Administrators',
163 'License :: OSI Approved :: GNU Affero General Public License v3',
164 'Operating System :: MacOS :: MacOS X',
165 'Operating System :: Microsoft :: Windows',
166 'Operating System :: POSIX',
167 'Programming Language :: Python',
168 'Topic :: System :: Monitoring',
169 'Topic :: System :: Networking :: Monitoring',
172 install_requires = [
173 required_pkgs
176 scripts = [f for f in glob('bin/shinken-[!_]*')],
177 data_files=[(etc_path, ["etc/nagios.cfg",'etc/brokerd.ini', 'etc/brokerd-windows.ini',
178 'etc/commands.cfg', 'etc/timeperiods.cfg', 'etc/templates.cfg',
179 'etc/escalations.cfg', 'etc/dependencies.cfg',
180 'etc/hostgroups.cfg', 'etc/servicegroups.cfg',
181 'etc/contactgroups.cfg',
182 'etc/nagios.cfg', 'etc/nagios-windows.cfg', 'etc/pollerd.ini',
183 'etc/reactionnerd.ini', 'etc/resource.cfg', 'etc/schedulerd.ini',
184 'etc/schedulerd-windows.ini', 'etc/pollerd-windows.ini',
185 'etc/shinken-specific.cfg', 'etc/shinken-specific-high-availability.cfg',
186 'etc/shinken-specific-load-balanced-only.cfg'
188 (os.sep.join([etc_path, 'objects', 'hosts']), [f for f in glob('etc/objects/hosts/[!_]*.cfg')]),
189 (os.sep.join([etc_path, 'objects', 'services']), [f for f in glob('etc/objects/services/[!_]*.cfg')]),
190 (os.sep.join([etc_path, 'objects', 'contacts']), [f for f in glob('etc/objects/contacts/[!_]*.cfg')]),
192 ('/etc/init.d', ['bin/init.d/shinken-arbiter', 'bin/init.d/shinken-broker', 'bin/init.d/shinken-poller',
193 'bin/init.d/shinken-reactionner', 'bin/init.d/shinken-scheduler', 'bin/init.d/shinken']),
194 ('/etc/default/', ['bin/default/shinken']),
195 (var_path, ['var/void_for_git']),
196 (libexec_path, ['libexec/check.sh']),
202 #Ok now the less good part :(
203 #I didn't find any easy way to get it :(
204 #We will chown shinken:shinken for all /etc/shinken
205 #and /var/lib/shinken.
206 def get_uid(user_name):
207 try:
208 return getpwnam(user_name)[2]
209 except KeyError, exp:
210 print "Error: the user", user_name, "is unknown"
211 print "Maybe you should create this user"
212 sys.exit(2)
215 def get_gid(group_name):
216 try:
217 return getgrnam(group_name)[2]
218 except KeyError, exp:
219 print "Error: the group",group_name , "is unknown"
220 print "Maybe you should create this group"
221 sys.exit(2)
224 #Open a /etc/*d.ini file and change the ../var occurence with a good value
225 #from the configuration file
226 def update_ini_file_with_var(path):
227 global paths_and_owners
228 var_path = paths_and_owners['var']['path']
229 update_file_with_string(path, "../var", var_path)
232 #Replace the libexec path in common.cfg by the one in the parameter file
233 def update_resource_cfg_file_with_libexec(path):
234 global paths_and_owners
235 libexec_path = paths_and_owners['libexec']['path']
236 update_file_with_string(path, "/usr/local/shinken/libexec", libexec_path)
239 #Replace paths in nagios.cfg file
240 def update_cfg_file_with_var_path(path):
241 global paths_and_owners
242 var_path = paths_and_owners['var']['path']
243 update_file_with_string(path, "/usr/local/shinken/var", var_path)
248 #Replace the libexec path in common.cfg by the one in the parameter file
249 def update_file_with_string(path, match, new_string):
250 f = open(path)
251 buf = f.read()
252 f.close
253 f = open(path, "w")
254 buf = buf.replace(match, new_string)
255 f.write(buf)
256 f.close()
260 #If there is another root, it's strange, it must be a special case...
261 if os.name != 'nt' and ('install' in sys.argv or 'sdist' in sys.argv) and re.search("--root", ' '.join(sys.argv)) == None:
262 for g_dir in ['etc', 'var']:
263 path = paths_and_owners[g_dir]['path']
264 owner = paths_and_owners[g_dir]['owner']
265 group = paths_and_owners[g_dir]['group']
266 uid = get_uid(owner)
267 gui = get_gid(group)
268 for root, dirs, files in os.walk(path):
269 print "Changing the directory", root, "by", owner, ":", group
270 os.chown(root, uid, gui)
271 for dir in dirs:
272 print "Change owner of the directory", root+os.sep+dir, "by", owner, ":", group
273 os.chown(root+os.sep+dir,uid, gui)
274 for name in files:
275 print "Change owner of the file", root+os.sep+name, "by", owner, ":", group
276 os.chown(root+os.sep+name,uid, gui)
280 #Here, even with --root we should change the file with good values
281 if os.name != 'nt' and ('install' in sys.argv or 'sdist' in sys.argv):
282 #then update the /etc/*d.ini files ../var value with the real var one
283 print "Now updating the /etc/shinken/*d/ini files with the good value for var"
284 update_ini_file_with_var(os.sep.join([root_path, etc_path, 'brokerd.ini']))
285 update_ini_file_with_var(os.sep.join([root_path, etc_path, 'schedulerd.ini']))
286 update_ini_file_with_var(os.sep.join([root_path, etc_path, 'pollerd.ini']))
287 update_ini_file_with_var(os.sep.join([root_path, etc_path, 'reactionnerd.ini']))
289 #And now the resource.cfg path with the value of libexec path
290 print "Now updating the /etc/shinken/resource.cfg file with good libexec path"
291 update_resource_cfg_file_with_libexec(os.sep.join([root_path, etc_path, 'resource.cfg']))
293 #And update the nagios.cfg file for all /usr/local/shinken/var value with good one
294 print "Now updating the /etc/shinken/nagios.cfg file with good var path"
295 update_cfg_file_with_var_path(os.sep.join([root_path, etc_path, 'nagios.cfg']))
296 update_cfg_file_with_var_path(os.sep.join([root_path, etc_path, 'shinken-specific.cfg']))