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 appy.gen.generator import GeneratorError, ZopeGenerator
 | 
			
		||||
from appy.shared.utils import LinesCounter
 | 
			
		||||
from appy.shared.packaging import Debianizer
 | 
			
		||||
from appy.shared.packaging import Debianizer, Cortexer
 | 
			
		||||
import appy.version
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +34,9 @@ S_OPTION = 'Sorts all i18n labels. If you use this option, among the ' \
 | 
			
		|||
           'set of translation files.'
 | 
			
		||||
D_OPTION = 'Generates a Debian package for this app. The Debian package will ' \
 | 
			
		||||
           '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:
 | 
			
		||||
    '''usage: %prog [options] app
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +71,8 @@ class GeneratorScript:
 | 
			
		|||
            dest='i18nSort', default=False, help=S_OPTION)
 | 
			
		||||
        optParser.add_option("-d", "--debian", action='store_true',
 | 
			
		||||
            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()
 | 
			
		||||
        try:
 | 
			
		||||
            self.manageArgs(optParser, options, args)
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +92,9 @@ class GeneratorScript:
 | 
			
		|||
                f.close()
 | 
			
		||||
                version = version[:version.find('build')-1]
 | 
			
		||||
                Debianizer(app, appDir, appVersion=version).run()
 | 
			
		||||
            # Generates a Cortex application definition if required
 | 
			
		||||
            if options.cortex:
 | 
			
		||||
                Cortexer(args[0]).run()
 | 
			
		||||
        except GeneratorError, ge:
 | 
			
		||||
            sys.stderr.write(str(ge))
 | 
			
		||||
            sys.stderr.write('\n')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ class ZopeInstanceCreator:
 | 
			
		|||
        os.mkdir('etc')
 | 
			
		||||
        f = file('etc/zope.conf', 'w')
 | 
			
		||||
        f.write(zopeConf % (self.instancePath, '%s/var' % self.instancePath,
 | 
			
		||||
                            '%s/log' % self.instancePath, ''))
 | 
			
		||||
                            '%s/log' % self.instancePath, '8080', ''))
 | 
			
		||||
        f.close()
 | 
			
		||||
        # Create other folders
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ zopeConf = '''# Zope configuration.
 | 
			
		|||
%%define INSTANCE %s
 | 
			
		||||
%%define DATA %s
 | 
			
		||||
%%define LOG %s
 | 
			
		||||
%%define HTTPPORT 8080
 | 
			
		||||
%%define HTTPPORT %s
 | 
			
		||||
%%define ZOPE_USER zope
 | 
			
		||||
 | 
			
		||||
instancehome $INSTANCE
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ class Debianizer:
 | 
			
		|||
       package.'''
 | 
			
		||||
 | 
			
		||||
    def __init__(self, app, out, appVersion='0.1.0',
 | 
			
		||||
                 pythonVersions=('2.6',),
 | 
			
		||||
                 pythonVersions=('2.6',), zopePort=8080,
 | 
			
		||||
                 depends=('zope2.12', 'openoffice.org', 'imagemagick')):
 | 
			
		||||
        # app is the path to the Python package to Debianize.
 | 
			
		||||
        self.app = app
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +118,8 @@ class Debianizer:
 | 
			
		|||
        self.appVersion = appVersion
 | 
			
		||||
        # On which Python versions will the Debian package depend?
 | 
			
		||||
        self.pythonVersions = pythonVersions
 | 
			
		||||
        # Port for Zope
 | 
			
		||||
        self.zopePort = zopePort
 | 
			
		||||
        # Debian package dependencies
 | 
			
		||||
        self.depends = depends
 | 
			
		||||
        # Zope 2.12 requires Python 2.6
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +191,7 @@ class Debianizer:
 | 
			
		|||
            productsFolder = '/usr/lib/python%s/%s/zope' % \
 | 
			
		||||
                             (self.pythonVersions[0], self.appName)
 | 
			
		||||
            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))
 | 
			
		||||
            f.close()
 | 
			
		||||
            # /etc/init.d/<app> (start the app at boot time)
 | 
			
		||||
| 
						 | 
				
			
			@ -305,4 +307,90 @@ class Debianizer:
 | 
			
		|||
        # Clean temp files
 | 
			
		||||
        FolderDeleter.delete(debFolder)
 | 
			
		||||
        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