appy.shared: added the possibility to generate a Cortex (see www.guardis.com) application definition for an Appy application.
This commit is contained in:
		
							parent
							
								
									57c481f05e
								
							
						
					
					
						commit
						69fb172f03
					
				
					 3 changed files with 102 additions and 6 deletions
				
			
		|  | @ -5,7 +5,7 @@ import sys, os.path | ||||||
| from optparse import OptionParser | from optparse import OptionParser | ||||||
| from appy.gen.generator import GeneratorError, ZopeGenerator | from appy.gen.generator import GeneratorError, ZopeGenerator | ||||||
| from appy.shared.utils import LinesCounter | from appy.shared.utils import LinesCounter | ||||||
| from appy.shared.packaging import Debianizer | from appy.shared.packaging import Debianizer, Cortexer | ||||||
| import appy.version | import appy.version | ||||||
| 
 | 
 | ||||||
| # ------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------ | ||||||
|  | @ -34,6 +34,9 @@ S_OPTION = 'Sorts all i18n labels. If you use this option, among the ' \ | ||||||
|            'set of translation files.' |            'set of translation files.' | ||||||
| D_OPTION = 'Generates a Debian package for this app. The Debian package will ' \ | D_OPTION = 'Generates a Debian package for this app. The Debian package will ' \ | ||||||
|            'be generated at the same level as the root application folder.' |            'be generated at the same level as the root application folder.' | ||||||
|  | X_OPTION = 'Generates a Cortex application definition for this app, in a ' \ | ||||||
|  |            'folder "cortex.admin" that will be generated at the same level ' \ | ||||||
|  |            'as the root application folder.' | ||||||
| 
 | 
 | ||||||
| class GeneratorScript: | class GeneratorScript: | ||||||
|     '''usage: %prog [options] app |     '''usage: %prog [options] app | ||||||
|  | @ -68,6 +71,8 @@ class GeneratorScript: | ||||||
|             dest='i18nSort', default=False, help=S_OPTION) |             dest='i18nSort', default=False, help=S_OPTION) | ||||||
|         optParser.add_option("-d", "--debian", action='store_true', |         optParser.add_option("-d", "--debian", action='store_true', | ||||||
|             dest='debian', default=False, help=D_OPTION) |             dest='debian', default=False, help=D_OPTION) | ||||||
|  |         optParser.add_option("-x", "--cortex", action='store_true', | ||||||
|  |             dest='cortex', default=False, help=X_OPTION) | ||||||
|         (options, args) = optParser.parse_args() |         (options, args) = optParser.parse_args() | ||||||
|         try: |         try: | ||||||
|             self.manageArgs(optParser, options, args) |             self.manageArgs(optParser, options, args) | ||||||
|  | @ -87,6 +92,9 @@ class GeneratorScript: | ||||||
|                 f.close() |                 f.close() | ||||||
|                 version = version[:version.find('build')-1] |                 version = version[:version.find('build')-1] | ||||||
|                 Debianizer(app, appDir, appVersion=version).run() |                 Debianizer(app, appDir, appVersion=version).run() | ||||||
|  |             # Generates a Cortex application definition if required | ||||||
|  |             if options.cortex: | ||||||
|  |                 Cortexer(args[0]).run() | ||||||
|         except GeneratorError, ge: |         except GeneratorError, ge: | ||||||
|             sys.stderr.write(str(ge)) |             sys.stderr.write(str(ge)) | ||||||
|             sys.stderr.write('\n') |             sys.stderr.write('\n') | ||||||
|  |  | ||||||
|  | @ -121,7 +121,7 @@ class ZopeInstanceCreator: | ||||||
|         os.mkdir('etc') |         os.mkdir('etc') | ||||||
|         f = file('etc/zope.conf', 'w') |         f = file('etc/zope.conf', 'w') | ||||||
|         f.write(zopeConf % (self.instancePath, '%s/var' % self.instancePath, |         f.write(zopeConf % (self.instancePath, '%s/var' % self.instancePath, | ||||||
|                             '%s/log' % self.instancePath, '')) |                             '%s/log' % self.instancePath, '8080', '')) | ||||||
|         f.close() |         f.close() | ||||||
|         # Create other folders |         # Create other folders | ||||||
|         for name in ('Extensions', 'log', 'Products', 'var'): os.mkdir(name) |         for name in ('Extensions', 'log', 'Products', 'var'): os.mkdir(name) | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| # ------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------ | ||||||
| import os, os.path, subprocess, md5, shutil | import os, os.path, subprocess, md5, shutil, random | ||||||
| from appy.shared.utils import getOsTempFolder, FolderDeleter, cleanFolder | from appy.shared.utils import getOsTempFolder, FolderDeleter, cleanFolder | ||||||
| 
 | 
 | ||||||
| # ------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------ | ||||||
|  | @ -31,7 +31,7 @@ zopeConf = '''# Zope configuration. | ||||||
| %%define INSTANCE %s | %%define INSTANCE %s | ||||||
| %%define DATA %s | %%define DATA %s | ||||||
| %%define LOG %s | %%define LOG %s | ||||||
| %%define HTTPPORT 8080 | %%define HTTPPORT %s | ||||||
| %%define ZOPE_USER zope | %%define ZOPE_USER zope | ||||||
| 
 | 
 | ||||||
| instancehome $INSTANCE | instancehome $INSTANCE | ||||||
|  | @ -106,7 +106,7 @@ class Debianizer: | ||||||
|        package.''' |        package.''' | ||||||
| 
 | 
 | ||||||
|     def __init__(self, app, out, appVersion='0.1.0', |     def __init__(self, app, out, appVersion='0.1.0', | ||||||
|                  pythonVersions=('2.6',), |                  pythonVersions=('2.6',), zopePort=8080, | ||||||
|                  depends=('zope2.12', 'openoffice.org', 'imagemagick')): |                  depends=('zope2.12', 'openoffice.org', 'imagemagick')): | ||||||
|         # app is the path to the Python package to Debianize. |         # app is the path to the Python package to Debianize. | ||||||
|         self.app = app |         self.app = app | ||||||
|  | @ -118,6 +118,8 @@ class Debianizer: | ||||||
|         self.appVersion = appVersion |         self.appVersion = appVersion | ||||||
|         # On which Python versions will the Debian package depend? |         # On which Python versions will the Debian package depend? | ||||||
|         self.pythonVersions = pythonVersions |         self.pythonVersions = pythonVersions | ||||||
|  |         # Port for Zope | ||||||
|  |         self.zopePort = zopePort | ||||||
|         # Debian package dependencies |         # Debian package dependencies | ||||||
|         self.depends = depends |         self.depends = depends | ||||||
|         # Zope 2.12 requires Python 2.6 |         # Zope 2.12 requires Python 2.6 | ||||||
|  | @ -189,7 +191,7 @@ class Debianizer: | ||||||
|             productsFolder = '/usr/lib/python%s/%s/zope' % \ |             productsFolder = '/usr/lib/python%s/%s/zope' % \ | ||||||
|                              (self.pythonVersions[0], self.appName) |                              (self.pythonVersions[0], self.appName) | ||||||
|             f.write(zopeConf % ('/var/lib/%s' % n, '/var/lib/%s' % n, |             f.write(zopeConf % ('/var/lib/%s' % n, '/var/lib/%s' % n, | ||||||
|                                 '/var/log/%s' % n, |                                 '/var/log/%s' % n, str(self.zopePort), | ||||||
|                                 'products %s\n' % productsFolder)) |                                 'products %s\n' % productsFolder)) | ||||||
|             f.close() |             f.close() | ||||||
|             # /etc/init.d/<app> (start the app at boot time) |             # /etc/init.d/<app> (start the app at boot time) | ||||||
|  | @ -305,4 +307,90 @@ class Debianizer: | ||||||
|         # Clean temp files |         # Clean temp files | ||||||
|         FolderDeleter.delete(debFolder) |         FolderDeleter.delete(debFolder) | ||||||
|         os.chdir(curdir) |         os.chdir(curdir) | ||||||
|  | 
 | ||||||
|  | # ------------------------------------------------------------------------------ | ||||||
|  | definitionJson = '''{ | ||||||
|  |   "name": "%s", | ||||||
|  |   "description": "%s, a Appy-based application", | ||||||
|  |   "packages": [{"name": "python-appy" }, {"name": "python-appy-%s" }], | ||||||
|  |   "files": [ | ||||||
|  |     { "group": "root", "mode": "644", "name": "%s.conf", | ||||||
|  |       "owner": "root", "path": "/etc/%s.conf", | ||||||
|  |       "template": "%s" | ||||||
|  |     }], | ||||||
|  |   "handlers": [ | ||||||
|  |     { "on": ["_install"] }, | ||||||
|  |     { "on": ["_uninstall" ] }, | ||||||
|  |     { "on": ["%s_http_port"], | ||||||
|  |       "do": [ | ||||||
|  |         { "action": "update", "resource": "file://%s.conf" },  | ||||||
|  |         { "action": "restart", "resource": "service://%s" } | ||||||
|  |       ]}, | ||||||
|  |     ],  | ||||||
|  |   "services": [ | ||||||
|  |     { "name": "%s", "enabled": "true", "running": "false" },  | ||||||
|  |     { "name": "oo",  "enabled": "true",  "running": "false" }],  | ||||||
|  | } | ||||||
|  | ''' | ||||||
|  | definitionJsonConf = '''{ | ||||||
|  |   "name": "%s.conf", | ||||||
|  |   "uuid": "%s", | ||||||
|  |   "parameters": [ | ||||||
|  |     { "key": "%s_http_port",  "name": "%s HTTP port", | ||||||
|  |       "description": "%s HTTP port for the Zope process", | ||||||
|  |       "value": "8080"} | ||||||
|  |   ], | ||||||
|  | } | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | class Cortexer: | ||||||
|  |     '''This class allows to produce a Cortex application definition for | ||||||
|  |        a Debianized Python/Appy application.''' | ||||||
|  |     def __init__(self, app, pythonVersions=('2.6',)): | ||||||
|  |         self.appName = os.path.basename(app) | ||||||
|  |         self.pythonVersions = pythonVersions | ||||||
|  |         appFolder = os.path.dirname(app) | ||||||
|  |         # Prepare the output folder (remove any existing one) | ||||||
|  |         cortexFolder = os.path.join(appFolder, 'cortex.admin') | ||||||
|  |         if os.path.exists(cortexFolder): | ||||||
|  |             FolderDeleter.delete(cortexFolder) | ||||||
|  |         allFolders = os.path.join(cortexFolder, 'applications', self.appName) | ||||||
|  |         os.makedirs(allFolders) | ||||||
|  |         self.out = allFolders | ||||||
|  | 
 | ||||||
|  |     uuidChars= ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'] | ||||||
|  |     def generateUid(self): | ||||||
|  |         '''Generates a 32-chars-wide UID for identifying the configuration file | ||||||
|  |            in the Cortex DB.''' | ||||||
|  |         res = '' | ||||||
|  |         for i in range(32): | ||||||
|  |             res += self.uuidChars[random.randint(0,15)] | ||||||
|  |         return res | ||||||
|  | 
 | ||||||
|  |     def run(self): | ||||||
|  |         # Create the root app description file "definition.json". | ||||||
|  |         uid = self.generateUid() | ||||||
|  |         name = os.path.join(self.out, 'definition.json') | ||||||
|  |         f = file(name, 'w') | ||||||
|  |         n = self.appName | ||||||
|  |         nl = self.appName.lower() | ||||||
|  |         f.write(definitionJson % (n, n, nl, nl, nl, uid, nl, nl, nl, nl)) | ||||||
|  |         f.close() | ||||||
|  |         # Create the folder corresponding to the config file, and its content. | ||||||
|  |         confFolder = os.path.join(self.out, '%s.conf' % nl) | ||||||
|  |         os.mkdir(confFolder) | ||||||
|  |         # Create the definition file for this config file, that will contain | ||||||
|  |         # the names of Cortex-managed variables within the configuration file. | ||||||
|  |         name = os.path.join(confFolder, 'definition.json') | ||||||
|  |         f = file(name, 'w') | ||||||
|  |         f.write(definitionJsonConf % (nl, uid, nl, n, n)) | ||||||
|  |         f.close() | ||||||
|  |         # Create the Zope config file, with Cortex-like variables within in. | ||||||
|  |         name = os.path.join(confFolder, '%s.conf' % nl) | ||||||
|  |         f = file(name, 'w') | ||||||
|  |         productsFolder='/usr/lib/python%s/%s/zope' % (self.pythonVersions[0],n) | ||||||
|  |         f.write(zopeConf % ('/var/lib/%s' % n, '/var/lib/%s' % n, | ||||||
|  |                             '/var/log/%s' % n, '${%s_http_port}' % nl, | ||||||
|  |                             'products %s\n' % productsFolder)) | ||||||
|  |         f.close() | ||||||
| # ------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gaetan Delannay
						Gaetan Delannay