appy.shared: added the possibility to generate a Cortex (see www.guardis.com) application definition for an Appy application.

This commit is contained in:
Gaetan Delannay 2012-02-14 12:52:36 +01:00
parent 57c481f05e
commit 69fb172f03
3 changed files with 102 additions and 6 deletions

View file

@ -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')

View file

@ -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)

View file

@ -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()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------