source: TI12-security/trunk/python/ndg-security-install.py @ 2948

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg-security-install.py@2953
Revision 2948, 11.5 KB checked in by pjkersha, 13 years ago (diff)

python/ndg.security.server/ndg/security/server/conf/sessionMgr.tac,
python/ndg.security.server/ndg/security/server/conf/attAuthority.tac:

  • fixed ref to _logConfig - only use if NDGSEC_DIR was set
  • fixes for epydoc
  • Stop in initialisation if NDGSEC_INT_DEBUG set.

python/ndg-security-install.py: added code to copy conf dir from egg to /etc/ndg/security/conf. - Use pkg_resources.resource_filename to ref egg conf dir.

python/Makefile: include ndg-security-install.py in install_eggs target

documentation/epydoc/*: updated epydoc

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2"""Install NDG Server package with M2Crypto build settings and to include
3Twisted
4
5NERC Data Grid Project
6"""
7__author__ = "P J Kershaw"
8__date__ = "15/03/07"
9__copyright__ = "(C) 2007 STFC & NERC"
10__license__ = \
11"""This software may be distributed under the terms of the Q Public
12License, version 1.0 or later."""
13__contact__ = "P.J.Kershaw@rl.ac.uk"
14__revision__ = '$Id$'
15
16
17import os, sys
18import pkg_resources # Locate ndg.security.server.conf dir
19import shutil # For creating config dir
20import urllib
21import optparse
22from ConfigParser import SafeConfigParser
23from subprocess import call
24from setuptools.command.easy_install import main
25       
26class SecurityInstallError(Exception):
27    """Errors related to security installation"""
28   
29class SecurityInstall(object):
30    '''Wrapper class for NDG security installation
31   
32    A wrapper is required over and above easy_install as additional setup
33    steps are required to enable for example custom build settings for
34    M2Crypto
35   
36    @cvar dependencyLink: default location for dependencies
37    @type dependencyLink: string
38   
39    @cvar defaultTwistedURI: default location for Twisted download
40    @type param: string
41   
42    @cvar configDir: default location for configuration directory "conf"
43    @type configDir: string'''
44   
45    dependencyLink = "http://ndg.nerc.ac.uk/dist/" 
46    defaultTwistedURI = \
47'http://tmrc.mit.edu/mirror/twisted/Twisted/2.2/TwistedSumo-2006-02-12.tar.bz2'
48    configDir = os.path.join("/etc", "ndg", "security", "conf")
49   
50    def __call__(self):
51        self.main()
52       
53    def main(self):
54        '''Parse command line args and execute the installation'''
55       
56        parser = optparse.OptionParser()
57       
58        parser.add_option("-a",
59                          "--install-all",
60                          dest="installAll",
61                          action="store_true",
62                          default=False,
63                          help="Install client AND server packages.")
64       
65        parser.add_option("-c",
66                          "--install-client",
67                          dest="installClient",
68                          action="store_true",
69                          default=False,
70                          help="Install client package only.")
71       
72        parser.add_option("-s",
73                          "--install-server",
74                          dest="installServer",
75                          action="store_true",
76                          default=False,
77                          help="Install server package only.")
78       
79        parser.add_option("-u",
80                          "--install-unittests",
81                          dest="installUnitTests",
82                          action="store_true",
83                          default=False,
84                          help="Install unit test package only.")
85       
86        parser.add_option("-o",
87                          "--openssl-path",
88                          dest="opensslPath",
89                          default='/usr/local/ssl',
90                          help="Path to openssl for M2Crypto to link with")
91       
92        parser.add_option("-n",
93                          "--no-twisted",
94                          dest="noTwisted",
95                          action="store_true",
96                          default=False,
97                          help=\
98"""Skip Twisted install.  This option applies to the \"all\" and \"server\"
99package options only.  Twisted is not needed for the client.""")
100       
101        parser.add_option("-t",
102                          "--twisted-uri",
103                          dest="twistedURI",
104                          default=self.__class__.defaultTwistedURI,
105                          help=\
106"""Provide an alternative location for Twisted download.  A .tar.bz type file
107is expected.  The default is \"%s\"""" % self.__class__.defaultTwistedURI)
108       
109        parser.add_option("-f",
110                          "--find-links",
111                          dest="dependencyLinks",
112                          default=self.__class__.dependencyLink,
113                          help=\
114                      'Set URLs to locate packages.  The default is "%s"' % \
115                      self.__class__.dependencyLink)
116       
117        parser.add_option("-U",
118                          "--upgrade",
119                          dest="upgrade",
120                          action="store_true",
121                          default=False,
122                          help=\
123          'force upgrade (search PyPI/dependency links for latest version)')
124   
125        configOpts = ("-C", "--config-dir")
126        parser.add_option(dest="configDir",
127                          default=self.__class__.configDir,
128                          help=\
129"""Specify a location for configuration files (server package only).  The
130default is \"%s\"""" % self.__class__.configDir,
131                          *configOpts)
132   
133        self.opt, args = parser.parse_args()
134   
135        # Sanity check
136        nInstallArgs = sum((self.opt.installClient, 
137                            self.opt.installServer,
138                            self.opt.installUnitTests, 
139                            self.opt.installAll))
140        if not nInstallArgs:
141            parser.error("At least one install option must be set")
142           
143        elif nInstallArgs > 1:
144            parser.error("Only one install option may be set")
145 
146        # Set M2Crypto build settings in a distutils config file
147        self.initM2CryptoDependencies() 
148   
149        # Installation based on flags set
150        if self.opt.upgrade:
151            args = ['-U']
152        else:
153            args = []
154     
155        # Add links for dependencies 
156        args += ['-f', self.opt.dependencyLinks]
157       
158        if self.opt.installClient:
159            args += ["ndg_security_client"]
160            main(args)
161           
162        elif self.opt.installServer:
163            args += ["ndg_security_server"]
164            import pdb;pdb.set_trace()
165            main(args)
166            self.installTwisted()
167           
168            # Config dir is part of server package only
169            self.createConfigDir()
170           
171        elif self.opt.installUnitTests:
172            args += ["ndg_security_test"]
173            main(args)
174            self.installTwisted()
175           
176        elif self.opt.installAll:
177            ndgSecurityArgs = args + ["ndg_security"]
178            main(ndgSecurityArgs)
179            ndgSecurityTestArgs = args + ["ndg_security_test"]
180            main(ndgSecurityArgs)
181            self.installTwisted()
182           
183           
184    def initM2CryptoDependencies(self):       
185        '''Set-up link path for openssl for M2Crypto build by creating a
186        distutils config file containing the include file and library file
187        paths'''
188       
189        opensslInclPath = os.path.join(self.opt.opensslPath, 'include')
190        opensslLibPath = os.path.join(self.opt.opensslPath, 'lib')
191       
192        distutilsCfgFilePath = os.path.join(sys.prefix,
193                                            'lib',
194                                            'python%s' % sys.version[:3],
195                                            'distutils',
196                                            'distutils.cfg')
197        configParser = SafeConfigParser()
198       
199        if configParser.read(distutilsCfgFilePath):
200            # File already exists
201            if not configParser.has_section('build_ext'):
202                configParser.add_section('build_ext')
203           
204            if configParser.has_option('build_ext', 'include_dirs'):
205                existingInclDirs=configParser.get('build_ext', 'include_dirs')
206               
207                if opensslInclPath not in existingInclDirs.split():
208                    includeDirs = "%s %s" % (opensslInclPath,existingInclDirs)
209                    configParser.set('build_ext', 'include_dirs', includeDirs)
210            else:
211                configParser.set('build_ext', 'include_dirs', opensslInclPath)
212           
213            if configParser.has_option('build_ext', 'library_dirs'):
214                existingLibDirs = configParser.get('build_ext','library_dirs')
215               
216                if opensslLibPath not in existingLibDirs.split():
217                    libraryDirs = "%s %s" % (opensslLibPath, existingLibDirs)
218                    configParser.set('build_ext', 'library_dirs', libraryDirs)
219            else:
220                configParser.set('build_ext', 'library_dirs', opensslLibPath)
221                                 
222        else:
223            # No config file present - make one
224            configParser.add_section('build_ext')
225            configParser.set('build_ext', 'include_dirs', opensslInclPath)
226            configParser.set('build_ext', 'library_dirs', opensslLibPath)
227           
228        configParser.write(open(distutilsCfgFilePath, 'w'))
229   
230   
231    def installTwisted(self):
232        '''Download and install twisted manually as it is not egg compatible
233        '''
234       
235        if self.opt.noTwisted:
236            return
237           
238        # Install Twisted sumo
239        try:
240            twistedTarBz = os.path.basename(self.opt.twistedURI)   
241            urllib.urlretrieve(self.opt.twistedURI, twistedTarBz)
242           
243        except IOError, (errMsg, e):
244            raise SecurityInstallError, \
245                'Error retrieving Twisted from "%s": %s' % \
246                                                (self.opt.twistedTarURI, e[1])
247        except Exception, e:
248            raise SecurityInstallError, \
249                'Error retrieving Twisted from "%s": %s' % \
250                                                (self.opt.twistedTarURI, e)
251
252        import tarfile
253       
254        twistedTar = tarfile.open(twistedTarBz, 'r:bz2')
255        for tarInfo in twistedTar:
256            twistedTar.extract(tarInfo)
257       
258        try:
259            twistedDir=os.path.splitext(os.path.splitext(twistedTarBz)[0])[0]
260        except Exception:
261            raise SecurityInstallError, \
262            'Error getting Twisted dir path from tar.bz file name: "%s"' % \
263                twistedTarBz
264       
265        os.chdir(twistedDir)
266        try: 
267            retCode = call([os.path.join(sys.prefix, 'bin', 'python'), 
268                            'setup.py', 
269                            'install'])
270        except OSError, e:
271            raise SecurityInstallError, \
272                        "Error calling setup install for Twisted: " + str(e)
273       
274        if retCode != 0:
275            raise SecurityInstallError, "Twisted setup install returned %d" %\
276                                        retCode
277       
278        os.chdir('..')
279
280
281    def createConfigDir(self):
282        """Copy configuration files for services from the server egg into
283        a config area.  The default is /etc/ndg/security/conf"""
284       
285        # Skip if not set
286        if not self.opt.configDir: 
287            return
288       
289        # Otherwise create - fix to rwx for owner and group only
290        confDirPath = os.path.dirname(self.opt.configDir)
291        try:
292            os.makedirs(confDirPath, mode=0770)
293        except OSError, e:
294            raise SecurityInstallError, \
295                "Creating configuration directory: %s" % e
296       
297        # Locate conf directory in active egg
298        eggConfigDir = pkg_resources.resource_filename('ndg.security.server',
299                                                       'conf')
300       
301        # Copy over conf directory from egg
302        try:
303            shutil.copytree(eggConfigDir, self.opt.configDir)
304        except OSError, e:
305            raise SecurityInstallError, \
306                "Copying configuration directory: %s" % e
307
308if __name__ == "__main__":
309    SecurityInstall()()
310     
Note: See TracBrowser for help on using the repository browser.