root/install.py

Revision 137, 10.4 kB (checked in by francois, 2 years ago)

Added configuration options for /var/lib

  • Property svn:executable set to *
Line 
1 #!/usr/bin/env python
2 #
3 # MobilEd install script
4 #
5 # This program is free software, distributed under the terms of
6 # the GNU General Public License Version 2.
7 # See the COPYING file included in this archive
8
9 import os, sys, shutil, compiler
10 from optparse import OptionParser
11
12 DefaultBinDir = '/usr/local/sbin'
13 DefaultDataDir = '/usr/share/mobiled'
14 DefaultEtcDir = '/etc/mobiled'
15 DefaultLogDir = '/var/log/mobiled'
16 DefaultLibDir = '/usr/lib/mobiled'
17 DefaultVarLibDir = '/var/lib/mobiled'
18
19 class InstallError(Exception):
20     """ Simple generic installation error exception """
21
22 def doMenu(DirBin, DirData, DirEtc, DirLog, DirLib, DirVarLib):
23    
24     def getInput(DefaultValue=''):
25         line = raw_input('>>').strip()
26         if len(line) > 0:
27             return line
28         else:
29             return DefaultValue
30    
31     print '\n+--------------------+\n|MobilEd installation|\n+--------------------+\n\n'
32
33     questions = (('Directory to place main executable in [%s]:' % DirBin, DirBin),
34                  ('Directory to install program data files [%s]:' % DirData, DirData),
35                  ('Directory for configuration files [%s]:' % DirEtc, DirEtc),
36                  ('Directory for plugin files [%s]:' % DirLib, DirLib),
37                  ('Directory for log files [%s]:' % DirLog, DirLog),
38                  ('Directory for dynamic application data [%s]:' % DirVarLib, DirVarLib))
39    
40     done = False
41     while not done:
42         print questions[0][0]
43         _binDir = getInput(questions[0][1])
44         print questions[1][0]
45         _dataDir = getInput(questions[1][1])
46         print questions[2][0]
47         _etcDir = getInput(questions[2][1])
48         print questions[3][0]
49         _libDir = getInput(questions[3][1])
50         print questions[4][0]
51         _logDir = getInput(questions[4][1])
52         print questions[5][0]
53         _varLibDir = getInput(questions[4][1])
54
55         print '\nSummary\n-------'
56         print 'Install program executable to:', _binDir
57         print 'Install program data files to:', _dataDir
58         print 'Install configuration files to:', _etcDir
59         print 'Directory to place plugins in:', _libDir
60         print 'Directory to place log files in:', _logDir
61         print 'Directory to use for application-generated data files:', _varLibDir
62         print '\nIs this OK? (y/n) [n]'
63         if getInput('n').lower() == 'y':
64             done = True
65         print
66
67     return (_binDir, _dataDir, _etcDir, _libDir, _logDir, _varLibDir)
68
69 def createDirs(DirList):
70     """ Makes sure all directories in <DirList> exist; creates them if they don't
71     
72     Raises InstallError: if directory does not exist, and could not be created
73     """
74     for directory in DirList:
75         try:
76             os.makedirs(directory)
77         except OSError, (errno, msg):
78             if errno == 13:
79                 raise InstallError, 'You do not have permissions to create directory: '+logDir
80             elif errno != 17:
81                 raise
82
83 def getRelPath(Target, LocalDir):
84     commonPrefix = os.path.commonprefix((LocalDir, Target))
85     commonRelDepth = len(commonPrefix.split('/'))-1
86     relDepth = len(LocalDir.split('/'))-commonRelDepth
87     return relDepth*'../'+Target[len(commonPrefix):]
88
89 def configure(DirBin, DirData, DirEtc, DirPlugins, DirLog, DirVarLib, SettingsFilename='./mobiled/settings.py', BinFilename='./bin/mobiled'):
90     """ Modifies the settings.py file in the mobiled root to point to the
91     specified dirs, and compiles it to bytecode.
92     
93     Raises InstallError: if any step could not be accomplished
94     """
95     #dirData = getRelPath(DirData, DirBin)
96     #dirEtc = getRelPath(DirEtc, DirData)
97     #dirPlugins = getRelPath(DirPlugins, DirData)
98     #dirLog = getRelPath(DirLog, DirData)
99       
100     try:
101         if not os.path.exists(SettingsFilename+'.orig'):
102             shutil.copy2(SettingsFilename, SettingsFilename+'.orig')
103         f = open(SettingsFilename+'.orig', 'r')
104         buff = f.read()
105         f.close()
106     except:
107         raise InstallError, 'Could not open MobilEd settings file for reading: '+SettingsFilename
108     buff = buff.replace("DIR_HOME = os.path.abspath(sys.path[0])+'/cache'", "DIR_HOME = '%s'" % DirVarLib)
109     buff = buff.replace("DIR_CONFIG = '/../../'.join((DIR_HOME,'etc'))", "DIR_CONFIG = '%s'" % DirEtc)
110     buff = buff.replace("DIR_LOG = DIR_HOME", "DIR_LOG = '%s'" % DirLog)
111     buff = buff.replace("DIR_PLUGINS = os.path.abspath(sys.path[0])", "DIR_PLUGINS = '%s'" % DirPlugins)
112     try:
113         f = open(SettingsFilename, 'w')
114         f.write(buff)
115         f.close()
116     except:
117         raise InstallError, 'Could not write to MobilEd settings file: '+SettingsFilename
118     try:
119         compiler.compileFile(SettingsFilename)
120     except:
121         raise InstallError, 'Could not compile MobilEd settings file: '+SettingsFilename
122        
123     try:
124         if not os.path.exists(BinFilename+'.orig'):
125             shutil.copy2(BinFilename, BinFilename+'.orig')
126         f = open(BinFilename+'.orig', 'r')
127         buff = f.read()
128         f.close()
129     except:
130         raise InstallError, 'Could not open MobilEd executable file for reading: '+BinFilename
131     buff = buff.replace("sys.path.insert(0, '../mobiled')", "sys.path.insert(0, '%s')" % DirData)
132     try:
133         f = open(BinFilename, 'w')
134         f.write(buff)
135         f.close()
136     except:
137         raise InstallError, 'Could not write to MobilEd executable file: '+BinFilename
138     try:
139         compiler.compileFile(BinFilename)
140     except:
141         raise InstallError, 'Could not compile MobilEd executable: '+BinFilename
142
143
144 def cpPythonFile(Src, Dest):
145     for ext in ('.py', '.pyc', '.pyo'):
146         try:
147             shutil.copy2(Src+ext, Dest)
148             print 'copying:',Src+ext
149         except IOError, (errno, msg):
150             if errno != 2:
151                 raise
152
153 def copyFiles(DirBin, DirData, DirEtc, DirLib, SrcDir='./mobiled', SrcExec='./bin/mobiled', SrcEtc='./etc'):
154     # Main data files
155     for filename in ('/mobiled', '/settings'):
156         cpPythonFile(SrcDir+filename, DirData)
157     for dataSubDir in ('/lib',):
158         shutil.copytree(SrcDir+dataSubDir, DirData+dataSubDir, symlinks=True)
159    
160     # Configuration files
161     for filename in os.listdir(SrcEtc):
162         # Skip subversion data
163         if filename == '.svn':
164             continue
165         filename = SrcEtc+'/'+filename
166         if os.path.isfile(filename):
167             print 'copying:',filename
168             shutil.copy2(filename, DirEtc)
169         else:
170             print 'copying tree:',filename
171             shutil.copytree(filename, DirEtc+'/'+os.path.basename(filename), symlinks=True)
172    
173     # Plugins
174     for pluginDir in ('/channels', '/datasources', '/requestinputs'):
175         print 'copying tree:',SrcDir+pluginDir
176         shutil.copytree(SrcDir+pluginDir, DirLib+pluginDir, symlinks=True)
177    
178     # MobilEd wrapper executable file
179     print 'copying:', SrcExec
180     shutil.copy2(SrcExec, DirBin)
181    
182     #shutil.copytree('./mobiled', DirBin+'/mobiled', symlinks=True)
183
184 def doInstall(DirBin, DirData, DirEtc, DirLib, DirLog, DirVarLib, CopyPrefix=''):
185     """ Wrapper 'make install'-type function """
186     try:
187         print 'Configuring...'
188         configure(DirBin, DirData, DirEtc, DirLib, DirLog, DirVarLib)
189         print 'Creating directories...'
190         createDirs((CopyPrefix+DirBin, CopyPrefix+DirData, CopyPrefix+DirEtc, CopyPrefix+DirLib, CopyPrefix+DirLog, CopyPrefix+DirVarLib))
191         print 'Copying files...'
192         copyFiles(CopyPrefix+DirBin, CopyPrefix+DirData, CopyPrefix+DirEtc, CopyPrefix+DirLib)
193     except InstallError, msg:
194         print 'Error:',msg
195         print 'Installation aborted.'
196         sys.exit(1)
197     print 'Done!'
198
199
200 if __name__ == '__main__':
201     parser = OptionParser()
202     parser.add_option('-a', action="store_true", dest='autoInstall', help='automatic install; do not ask questions')
203     parser.add_option('--no-destdir-config', action='store_true', dest='noDestdirConfig', help='use DESTDIR prefix (if given) for file copying only, not for configuration (useful for packaging)')
204     parser.add_option('--DESTDIR', dest='rootDir', help='specify a root directory prefix; defaults to /')
205     parser.add_option('--BINDIR', dest='binDir', help='directory to place main executable program in; defaults to %s' % DefaultBinDir)
206     parser.add_option('--DATADIR', dest='dataDir', help='directory to install program data files; defaults to %s' % DefaultDataDir)
207     parser.add_option('--LOGDIR', dest='logDir', help='directory for log files; defaults to %s' % DefaultLogDir)
208     parser.add_option('--CONFDIR', dest='etcDir', help='directory for configuration files; defaults to %s' % DefaultEtcDir)
209     parser.add_option('--PLUGINDIR', dest='libDir', help='directory for plugins; defaults to %s' % DefaultLibDir)
210     parser.add_option('--VARLIBDIR', dest='varLibDir', help='directory for dynamic application-generated data files; defaults to %s' % DefaultVarLibDir)
211     parser.parse_args()
212    
213     if parser.values.rootDir == None:
214         parser.values.rootDir = ''
215     if parser.values.binDir == None:
216         parser.values.binDir = DefaultBinDir
217     if parser.values.dataDir == None:
218         parser.values.dataDir = DefaultDataDir
219     if parser.values.etcDir == None:
220         parser.values.etcDir = DefaultEtcDir
221     if parser.values.logDir == None:
222         parser.values.logDir = DefaultLogDir
223     if parser.values.libDir == None:
224         parser.values.libDir = DefaultLibDir
225     if parser.values.varLibDir == None:
226         parser.values.varLibDir = DefaultVarLibDir
227
228     if not parser.values.noDestdirConfig:
229         binDir = parser.values.rootDir+parser.values.binDir
230         dataDir = parser.values.rootDir+parser.values.dataDir
231         etcDir = parser.values.rootDir+parser.values.etcDir
232         logDir = parser.values.rootDir+parser.values.logDir
233         libDir = parser.values.rootDir+parser.values.libDir
234         varLibDir = parser.values.rootDir+parser.values.varLibDir
235         cpPrefix = ''
236     else:
237         binDir = parser.values.binDir
238         dataDir = parser.values.dataDir
239         etcDir = parser.values.etcDir
240         logDir = parser.values.logDir
241         libDir = parser.values.libDir
242         varLibDir = parser.values.varLibDir
243         cpPrefix = parser.values.rootDir
244    
245     try:
246         if not parser.values.autoInstall:
247             binDir, dataDir, etcDir, libDir, logDir, varLibDir = doMenu(binDir, dataDir, etcDir, logDir, libDir, varLibDir)
248
249         doInstall(binDir, dataDir, etcDir, libDir, logDir, varLibDir, cpPrefix)
250     except KeyboardInterrupt:
251         print '\nUser cancelled, aborting installation...'
252 else:
253     print 'This install script should be called directly.'
254     sys.exit(1)
255
Note: See TracBrowser for help on using the browser.