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

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

Fixes to tickets #828 #829

ndg.security.server/ndg/security/server/AttAuthority/server-config.tac,
ndg.security.server/ndg/security/server/ca/server-config.tac,
ndg.security.server/ndg/security/server/SessionMgr/server-config.tac:

  • Split import for wsSecurity into common component (no Zope or Twisted) and

server component (Zope and Twisted imports)

ndg.security.server/ndg/security/server/twisted.py:

  • new module to contain Twisted handler code for NDG-Security server egg.

This code is removed from common.wsSecurity so that the client egg no longer
has any Twisted or Zope dependencies

ndg.security.common/ndg/security/common/wsSecurity.py: removed Twisted handler
code and moved to new server.twisted module

ndg-security-install.py: add new --config-dir option to copy server egg conf/
dir contents to /etc/ndg/security on target host. Incomplete as a way to
programmatically get the egg site-packages/ location is needed.

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