[Checkins] SVN: keas.build/ first upload
Adam Groszer
agroszer at gmail.com
Tue Aug 11 04:54:51 EDT 2009
Log message for revision 102652:
first upload
Changed:
A keas.build/branches/
A keas.build/tags/
A keas.build/trunk/
A keas.build/trunk/CHANGES.txt
A keas.build/trunk/README.txt
A keas.build/trunk/bootstrap.py
A keas.build/trunk/buildout.cfg
A keas.build/trunk/setup.py
A keas.build/trunk/src/
A keas.build/trunk/src/keas/
A keas.build/trunk/src/keas/__init__.py
A keas.build/trunk/src/keas/build/
A keas.build/trunk/src/keas/build/__init__.py
A keas.build/trunk/src/keas/build/base.py
A keas.build/trunk/src/keas/build/build.py
A keas.build/trunk/src/keas/build/deploy.py
A keas.build/trunk/src/keas/build/install.py
A keas.build/trunk/src/keas/build/package.py
A keas.build/trunk/src/keas/build/sample/
A keas.build/trunk/src/keas/build/sample/buildout.cfg
A keas.build/trunk/src/keas/build/sample/moo/
A keas.build/trunk/src/keas/build/sample/moo/Deploy.cfg
A keas.build/trunk/src/keas/build/sample/moo/Installers.cfg
A keas.build/trunk/src/keas/build/sample/moo/moo-Instance-Template.cfg
A keas.build/trunk/src/keas/build/sample/moo/moo-Project-Build.cfg
A keas.build/trunk/src/keas/build/sample/moo/moo-Release-Template.cfg
A keas.build/trunk/src/keas/build/ssh.py
-=-
Property changes on: keas.build/trunk
___________________________________________________________________
Added: svn:ignore
+ .installed.cfg
bin
develop-eggs
parts
Added: keas.build/trunk/CHANGES.txt
===================================================================
--- keas.build/trunk/CHANGES.txt (rev 0)
+++ keas.build/trunk/CHANGES.txt 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,15 @@
+=======
+CHANGES
+=======
+
+0.1.1
+-----
+
+- Bug Fix: If a proejct variant is specified for which no release have
+ been made, the build script now exits nicely with a human readable
+ error message.
+
+0.1.0
+-----
+
+- Initial release.
Property changes on: keas.build/trunk/CHANGES.txt
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/README.txt
===================================================================
--- keas.build/trunk/README.txt (rev 0)
+++ keas.build/trunk/README.txt 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1 @@
+A Build System for Keas.
Property changes on: keas.build/trunk/README.txt
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/bootstrap.py
===================================================================
--- keas.build/trunk/bootstrap.py (rev 0)
+++ keas.build/trunk/bootstrap.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Property changes on: keas.build/trunk/bootstrap.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/buildout.cfg
===================================================================
--- keas.build/trunk/buildout.cfg (rev 0)
+++ keas.build/trunk/buildout.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,30 @@
+[buildout]
+extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+develop = .
+parts = scripts python test coverage-test coverage-report
+versions = versions
+
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = keas.build [test]
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = keas.build [test]
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
+
+[python]
+recipe = zc.recipe.egg
+interpreter = python
+eggs = keas.build
+
+[scripts]
+recipe = zc.recipe.egg
+eggs = keas.build
\ No newline at end of file
Property changes on: keas.build/trunk/buildout.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/setup.py
===================================================================
--- keas.build/trunk/setup.py (rev 0)
+++ keas.build/trunk/setup.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,72 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Package setup.
+
+$Id$
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(
+ name='keas.build',
+ version = '0.1.3dev',
+ author = "Stephan Richter and the Zope Community",
+ author_email = "zope-dev at zope.org",
+ description='A Build System',
+ long_description=(
+ read('README.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ license = "ZPL 2.1",
+ keywords = "zope3 release build",
+ classifiers = [
+ 'Development Status :: 4 - Beta',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Framework :: Zope3'],
+ url = 'http://pypi.python.org/pypi/keas.build',
+ packages = find_packages('src'),
+ include_package_data = True,
+ package_dir = {'': 'src'},
+ namespace_packages = ['keas'],
+ extras_require=dict(
+ test=[
+ 'zope.testing',
+ ],
+ ),
+ install_requires=[
+ 'BeautifulSoup',
+ #'pycrypto',
+ 'Twisted',
+ 'lxml',
+ 'setuptools',
+ ],
+ zip_safe = False,
+ entry_points = """
+ [console_scripts]
+ build = keas.build.build:main
+ build-package = keas.build.package:main
+ install = keas.build.install:main
+ deploy = keas.build.deploy:main
+ """,
+ )
Property changes on: keas.build/trunk/setup.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Property changes on: keas.build/trunk/src
___________________________________________________________________
Added: svn:ignore
+ keas.build.egg-info
Added: keas.build/trunk/src/keas/__init__.py
===================================================================
--- keas.build/trunk/src/keas/__init__.py (rev 0)
+++ keas.build/trunk/src/keas/__init__.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,7 @@
+try:
+ # Declare this a namespace package if pkg_resources is available.
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ pass
+
Property changes on: keas.build/trunk/src/keas/__init__.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/__init__.py
===================================================================
--- keas.build/trunk/src/keas/build/__init__.py (rev 0)
+++ keas.build/trunk/src/keas/build/__init__.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1 @@
+# Make a package.
Property changes on: keas.build/trunk/src/keas/build/__init__.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/base.py
===================================================================
--- keas.build/trunk/src/keas/build/base.py (rev 0)
+++ keas.build/trunk/src/keas/build/base.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,147 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Build a release
+
+$Id$
+"""
+__docformat__ = 'ReStructuredText'
+import StringIO
+import base64
+import httplib
+import logging
+import optparse
+import os
+import pkg_resources
+import subprocess
+import sys
+import urllib2
+import urlparse
+
+logger = logging.Logger('build')
+formatter = logging.Formatter('%(levelname)s - %(message)s')
+
+BUILD_SECTION = 'build'
+
+def do(cmd):
+ logger.debug('Command: ' + cmd)
+ p = subprocess.Popen(
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ logger.error(u'An error occurred while running command: %s' %cmd)
+ logger.error('Error Output: \n' + stderr)
+ sys.exit(p.returncode)
+ logger.debug('Output: \n' + stdout)
+ return stdout
+
+def getInput(prompt, default, useDefaults):
+ if useDefaults:
+ return default
+ defaultStr = ''
+ if default:
+ defaultStr = ' [' + default + ']'
+ value = raw_input(prompt + defaultStr + ': ')
+ if not value:
+ return default
+ return value
+
+
+def uploadFile(path, url, username, password, offline):
+ filename = os.path.split(path)[-1]
+ if offline:
+ logger.info('Offline: File `%s` not uploaded.' %filename)
+ logger.debug('Uploading `%s` to %s' %(filename, url))
+ pieces = urlparse.urlparse(url)
+ Connection = httplib.HTTPConnection
+ if pieces[0] == 'https':
+ Connection = httplib.HTTPSConnection
+
+ base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
+
+ conn = Connection(pieces[1])
+ conn.request(
+ 'PUT',
+ pieces[2]+'/'+filename,
+ open(path, 'r').read(),
+ {"Authorization": "Basic %s" % base64string})
+
+ response = conn.getresponse()
+ if response.status != 201:
+ logger.error('Error uploading file. Code: %i (%s)' %(
+ response.status, response.reason))
+ else:
+ logger.info('File uploaded: %s' %filename)
+
+
+def guessNextVersion(version):
+ pieces = pkg_resources.parse_version(version)
+ newPieces = []
+ for piece in pieces:
+ try:
+ newPieces.append(int(piece))
+ except ValueError:
+ break
+ newPieces += [0]*(3-len(newPieces))
+ newPieces[-1] += 1
+ newVersion = '.'.join([str(piece) for piece in newPieces])
+ logger.debug('Last Version: %s -> %s' %(version, newVersion))
+ return newVersion
+
+
+parser = optparse.OptionParser()
+parser.add_option(
+ "-c", "--config-file", action="store",
+ dest="configFile", metavar="FILE",
+ help="The file containing the configuration of the project.")
+
+parser.add_option(
+ "-q", "--quiet", action="store_true",
+ dest="quiet", default=False,
+ help="When specified, no messages are displayed.")
+
+parser.add_option(
+ "-v", "--verbose", action="store_true",
+ dest="verbose", default=False,
+ help="When specified, debug information is created.")
+
+parser.add_option(
+ "-d", "--use-defaults", action="store_true",
+ dest="useDefaults", default=False,
+ help="When specified, no user input is required and the defaults are used.")
+
+parser.add_option(
+ "-o", "--offline-mode", action="store_true",
+ dest="offline", default=False,
+ help="When set, no server commands are executed.")
+
+parser.add_option(
+ "-n", "--next-version", action="store_true",
+ dest="nextVersion", default=False,
+ help="When set, the system guesses the next version to generate.")
+
+parser.add_option(
+ "-b", "--use-branch", action="store",
+ dest="branch", metavar="BRANCH", default=None,
+ help="When specified, this branch will be always used.")
+
+parser.add_option(
+ "--no-upload", action="store_true",
+ dest="noUpload", default=False,
+ help="When set, the generated configuration files are not uploaded.")
+
+parser.add_option(
+ "--no-branch-update", action="store_true",
+ dest="noBranchUpdate", default=False,
+ help=("When set, the branch is not updated with a new version after a "
+ "release is created."))
Property changes on: keas.build/trunk/src/keas/build/base.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/build.py
===================================================================
--- keas.build/trunk/src/keas/build/build.py (rev 0)
+++ keas.build/trunk/src/keas/build/build.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,167 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Build a release
+
+$Id$
+"""
+__docformat__ = 'ReStructuredText'
+import BeautifulSoup
+import ConfigParser
+import StringIO
+import base64
+import logging
+import pkg_resources
+import re
+import sys
+import urllib2
+from keas.build import base, package
+
+logger = base.logger
+
+def findProjectVersions(project, config, options):
+ if options.offline:
+ logger.info('Offline: Skip looking for project versions.')
+ return []
+ url = config.get(base.BUILD_SECTION, 'buildout-server') + project + '/'
+ logger.debug('Package Index: ' + url)
+ req = urllib2.Request(url)
+
+ username = config.get(base.BUILD_SECTION, 'buildout-server-username')
+ password = config.get(base.BUILD_SECTION, 'buildout-server-password')
+ base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
+ req.add_header("Authorization", "Basic %s" % base64string)
+
+ try:
+ soup = BeautifulSoup.BeautifulSoup(urllib2.urlopen(req).read())
+ except urllib2.HTTPError, err:
+ logger.error("There was an error accessing %s: %s" % (url, err))
+ return []
+ versions = [tag.contents[0][len(project)+1:-4]
+ for tag in soup('a')
+ if re.match(project+'-[0-9]', tag.contents[0])]
+
+ return sorted(versions, key=lambda x: pkg_resources.parse_version(x))
+
+
+def build(configFile, options):
+ # Read the configuration file.
+ logger.info('Loading configuration file: ' + configFile)
+ config = ConfigParser.RawConfigParser()
+ config.read(configFile)
+
+ # Create the project config parser
+ logger.info('Creating Project Configuration')
+ projectParser = ConfigParser.RawConfigParser()
+ if config.has_option(base.BUILD_SECTION, 'template'):
+ template = config.get(base.BUILD_SECTION, 'template')
+ logger.info('Loading Project Configuration Template: ' + template)
+ projectParser.read([template])
+ if not projectParser.has_section('versions'):
+ projectParser.add_section('versions')
+
+ # Determine all versions of the important packages
+ for pkg in config.get(base.BUILD_SECTION, 'packages').split():
+ customPath = None
+ if ':' in pkg:
+ pkg, customPath = pkg.split(':')
+ builder = package.PackageBuilder(pkg, options)
+ version = builder.runCLI(configFile, True)
+ projectParser.set('versions', pkg, version)
+
+ # Write the new configuration file to disk
+ projectName = config.get(base.BUILD_SECTION, 'name')
+ defaultVersion = configVersion = config.get(base.BUILD_SECTION, 'version')
+ projectVersions = findProjectVersions(projectName, config, options)
+ if projectVersions:
+ defaultVersion = projectVersions[-1]
+ if options.nextVersion or configVersion == '+':
+ defaultVersion = base.guessNextVersion(defaultVersion)
+ projectVersion = base.getInput(
+ 'Project Version', defaultVersion, options.useDefaults)
+
+ projectConfigFilename = '%s-%s.cfg' %(projectName, projectVersion)
+ logger.info('Writing project configuration file: ' + projectConfigFilename)
+ projectParser.write(open(projectConfigFilename, 'w'))
+
+ # Upload the release file
+ if not options.offline and not options.noUpload:
+ base.uploadFile(
+ projectConfigFilename,
+ config.get(base.BUILD_SECTION, 'buildout-server')+'/'+projectName,
+ config.get(base.BUILD_SECTION, 'buildout-server-username'),
+ config.get(base.BUILD_SECTION, 'buildout-server-password'),
+ options.offline)
+
+ # Create deployment configurations
+ for section in config.sections():
+ if section == base.BUILD_SECTION:
+ continue
+ logger.info('Building deployment configuration: ' + section)
+ logger.info('Loading deploy template file: ' +
+ config.get(section, 'template'))
+ template = file(config.get(section, 'template'), 'r').read()
+ vars = dict([(name, value) for name, value in config.items(section)
+ if name != 'template'])
+ vars['project-name'] = projectName
+ vars['project-version'] = projectVersion
+ vars['instance-name'] = section
+ deployConfigText = template %vars
+ deployConfigFilename = '%s-%s-%s.cfg' %(
+ config.get(base.BUILD_SECTION, 'name'), section, projectVersion)
+ deployConfig = ConfigParser.RawConfigParser()
+ deployConfig.readfp(StringIO.StringIO(deployConfigText))
+ deployConfig.set('buildout', 'extends', projectConfigFilename)
+ logger.info('Writing deployment file: ' + deployConfigFilename)
+ deployConfig.write(open(deployConfigFilename, 'w'))
+
+ # Upload the deployment file
+ if not options.offline and not options.noUpload:
+ base.uploadFile(
+ deployConfigFilename,
+ config.get(
+ base.BUILD_SECTION, 'buildout-server')+'/'+projectName,
+ config.get(base.BUILD_SECTION, 'buildout-server-username'),
+ config.get(base.BUILD_SECTION, 'buildout-server-password'),
+ options.offline)
+
+
+def main(args=None):
+ # Make sure we get the arguments.
+ if args is None:
+ args = sys.argv[1:]
+ if not args:
+ args = ['-h']
+
+ # Set up logger handler
+ handler = logging.StreamHandler(sys.stdout)
+ formatter = logging.Formatter('%(levelname)s - %(message)s')
+ handler.setFormatter(base.formatter)
+ logger.addHandler(handler)
+
+ # Parse arguments
+ options, args = base.parser.parse_args(args)
+
+ logger.setLevel(logging.INFO)
+ if options.verbose:
+ logger.setLevel(logging.DEBUG)
+ if options.quiet:
+ logger.setLevel(logging.FATAL)
+
+ build(options.configFile, options)
+
+ # Remove the handler again.
+ logger.removeHandler(handler)
+
+ # Exit cleanly.
+ sys.exit(0)
Property changes on: keas.build/trunk/src/keas/build/build.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/deploy.py
===================================================================
--- keas.build/trunk/src/keas/build/deploy.py (rev 0)
+++ keas.build/trunk/src/keas/build/deploy.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Package Deployment
+
+$Id$
+"""
+__docformat__ = 'ReStructuredText'
+import ConfigParser
+import logging
+import optparse
+import subprocess
+import sys
+from keas.build import base, ssh
+
+logger = base.logger
+
+def doSSH(cmd, host, username, password):
+ logger.info('%s:%s@%s # %s' %(username, password, host, cmd))
+ # Since I am too stupid to understand twisted, we execute the ssh command
+ # in a sub-process.
+ line = sys.executable
+ line += ' -c "import sys; sys.path = %r; ' %sys.path
+ line += 'from keas.build import ssh; '
+ line += 'print ssh.run(%r, %r, %r, %r)"' %(cmd, host, username, password)
+ p = subprocess.Popen(
+ line,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ p.wait()
+ if p.returncode != 0:
+ logger.error(u'An error occurred while running command: %s' %cmd)
+ error = p.stderr.read()
+ logger.error('Error Output: \n' + error)
+ sys.exit(p.returncode)
+ error = p.stderr.read()
+ if error:
+ logger.error('Error Output: \n' + error)
+ output = p.stdout.read()
+ if output:
+ logger.debug('Output: \n' + output)
+ return output
+
+class Deployment(object):
+
+ def __init__(self, options):
+ self.options = options
+
+ def runCLI(self):
+ # 1. Read the configuration file.
+ logger.info('Loading configuration file: ' + self.options.configFile)
+ config = ConfigParser.RawConfigParser()
+ config.read(self.options.configFile)
+ # 2. Deploy each component listed in the configuration
+ for section in config.sections():
+ logger.info('Deploying ' + section)
+ for cmd in config.get(section, 'commands').strip().split('\n'):
+ logger.debug('Run command: ' + cmd)
+ result = doSSH(
+ cmd,
+ config.get(section, 'server'),
+ config.get(section, 'username'),
+ config.get(section, 'password'))
+ logger.debug(result)
+
+parser = optparse.OptionParser()
+parser.add_option(
+ "-c", "--config-file", action="store",
+ dest="configFile", metavar="FILE",
+ help="The file containing the deployment configuration.")
+
+parser.add_option(
+ "-q", "--quiet", action="store_true",
+ dest="quiet", default=False,
+ help="When specified, no messages are displayed.")
+
+parser.add_option(
+ "-v", "--verbose", action="store_true",
+ dest="verbose", default=False,
+ help="When specified, debug information is created.")
+
+def main(args=None):
+ # Make sure we get the arguments.
+ if args is None:
+ args = sys.argv[1:]
+ if not args:
+ args = ['-h']
+
+ # Set up logger handler
+ handler = logging.StreamHandler(sys.stdout)
+ handler.setFormatter(base.formatter)
+ logger.addHandler(handler)
+
+ # Parse arguments
+ options, args = parser.parse_args(args)
+
+ logger.setLevel(logging.INFO)
+ if options.verbose:
+ logger.setLevel(logging.DEBUG)
+ if options.quiet:
+ logger.setLevel(logging.FATAL)
+
+ deployment = Deployment(options)
+ deployment.runCLI()
+
+ # Remove the handler again.
+ logger.removeHandler(handler)
+
+ # Exit cleanly.
+ sys.exit(0)
Property changes on: keas.build/trunk/src/keas/build/deploy.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/install.py
===================================================================
--- keas.build/trunk/src/keas/build/install.py (rev 0)
+++ keas.build/trunk/src/keas/build/install.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,220 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Package Builder
+
+$Id$
+"""
+__docformat__ = 'ReStructuredText'
+import BeautifulSoup
+import base64
+import logging
+import optparse
+import pkg_resources
+import re
+import sys
+import urllib2
+from keas.build import base
+
+logger = base.logger
+
+class Installer(object):
+
+ def __init__(self, options):
+ self.options = options
+
+ def getProjects(self):
+ logger.debug('Package Index: ' + self.options.url)
+ req = urllib2.Request(self.options.url)
+
+ if self.options.username:
+ base64string = base64.encodestring(
+ '%s:%s' % (self.options.username, self.options.password))[:-1]
+ req.add_header("Authorization", "Basic %s" % base64string)
+
+ soup = BeautifulSoup.BeautifulSoup(urllib2.urlopen(req).read())
+ projects = [tag.get('href').replace('/', '')
+ for tag in soup('a')
+ if tag.parent.name == 'td' and tag.get('href') != '/']
+ projects = sorted(projects)
+ logger.debug('Found projects: %s' %' '.join(projects))
+ return projects
+
+ def getVariants(self, project):
+ logger.debug('Package Index: ' + self.options.url)
+ req = urllib2.Request(self.options.url + project)
+
+ if self.options.username:
+ base64string = base64.encodestring(
+ '%s:%s' % (self.options.username, self.options.password))[:-1]
+ req.add_header("Authorization", "Basic %s" % base64string)
+
+ soup = BeautifulSoup.BeautifulSoup(urllib2.urlopen(req).read())
+ variants = []
+ for tag in soup('a'):
+ text = tag.contents[0]
+ if not text.startswith(project):
+ continue
+ if len(text.split('-')) != 3:
+ continue
+ variant = text.split('-')[1]
+ if variant in variants:
+ continue
+ variants.append(variant)
+ variants = sorted(variants)
+ logger.debug('Found variants: %s' %' '.join(variants))
+ return variants
+
+ def getVersions(self, project, variant):
+ logger.debug('Package Index: ' + self.options.url)
+ req = urllib2.Request(self.options.url + project)
+
+ if self.options.username:
+ base64string = base64.encodestring(
+ '%s:%s' % (self.options.username, self.options.password))[:-1]
+ req.add_header("Authorization", "Basic %s" % base64string)
+
+ soup = BeautifulSoup.BeautifulSoup(urllib2.urlopen(req).read())
+ versions = []
+ for tag in soup('a'):
+ text = tag.contents[0]
+ if not text.startswith(project+'-'+variant):
+ continue
+ version = text.split('-')[-1][:-4]
+ if version in versions:
+ continue
+ versions.append(version)
+ versions = sorted(
+ versions, key=lambda x: pkg_resources.parse_version(x))
+ logger.debug('Found versions: %s' %' '.join(versions))
+ return versions
+
+ def runCLI(self):
+ # 1. Get the project to be installed.
+ project = self.options.project
+ if project is None:
+ projects = self.getProjects()
+ print 'Projects'
+ for name in projects:
+ print ' * ' + name
+ project = base.getInput('Project', projects[0], False)
+ # 2. Get the variant of the project.
+ variant = self.options.variant
+ if variant is None:
+ variants = self.getVariants(project)
+ print 'Variants'
+ for name in variants:
+ print ' * ' + name
+ variant = base.getInput('Variant', variants[0], False)
+ # 3. Get the version of the project.
+ version = self.options.version
+ if version is None:
+ versions = self.getVersions(project, variant)
+ if len(versions) == 0:
+ print "Sorry, but there have not been any", project, variant, "releases yet."
+ sys.exit(0)
+ if self.options.latest:
+ version = versions[-1]
+ else:
+ print 'Versions'
+ for name in versions:
+ print ' * ' + name
+ version = base.getInput('Version', versions[-1], False)
+ # 4. Install the package
+ base.do('%s -t 2 -%sc %s%s/%s-%s-%s.cfg' %(
+ self.options.buildout,
+ "vvvvv" if self.options.verbose else "",
+ self.options.url,
+ project,
+ project, variant, version))
+
+parser = optparse.OptionParser()
+parser.add_option(
+ "-u", "--url", action="store",
+ dest="url", metavar="URL",
+ help="The base URL at which the releases can be found.")
+
+parser.add_option(
+ "-p", "--project", action="store",
+ dest="project", metavar="PROJECT",
+ help="The name of the project to be installed.")
+
+parser.add_option(
+ "-V", "--variant", action="store",
+ dest="variant", metavar="VARIANT",
+ help="The variant of the project to be installed.")
+
+parser.add_option(
+ "-v", "--version", action="store",
+ dest="version", metavar="VERSION",
+ help="The version of the project to be installed.")
+
+parser.add_option(
+ "-l", "--latest", action="store_true",
+ dest="latest", default=False,
+ help="When specified, the latest version will be chosen.")
+
+parser.add_option(
+ "--username", action="store",
+ dest="username", metavar="USER", default=None,
+ help="The username needed to access the site.")
+
+parser.add_option(
+ "--password", action="store",
+ dest="password", metavar="PASSWORD",
+ help="The password needed to access the site.")
+
+parser.add_option(
+ "-b", "--buildout-path", action="store",
+ dest="buildout", metavar="PATH", default="buildout",
+ help="The path to the buildout executable.")
+
+parser.add_option(
+ "--quiet", action="store_true",
+ dest="quiet", default=False,
+ help="When specified, no messages are displayed.")
+
+parser.add_option(
+ "--verbose", action="store_true",
+ dest="verbose", default=False,
+ help="When specified, debug information is created.")
+
+def main(args=None):
+ # Make sure we get the arguments.
+ if args is None:
+ args = sys.argv[1:]
+ if not args:
+ args = ['-h']
+
+ # Set up logger handler
+ handler = logging.StreamHandler(sys.stdout)
+ handler.setFormatter(base.formatter)
+ logger.addHandler(handler)
+
+ # Parse arguments
+ options, args = parser.parse_args(args)
+
+ logger.setLevel(logging.INFO)
+ if options.verbose:
+ logger.setLevel(logging.DEBUG)
+ if options.quiet:
+ logger.setLevel(logging.FATAL)
+
+ installer = Installer(options)
+ installer.runCLI()
+
+ # Remove the handler again.
+ logger.removeHandler(handler)
+
+ # Exit cleanly.
+ sys.exit(0)
Property changes on: keas.build/trunk/src/keas/build/install.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/package.py
===================================================================
--- keas.build/trunk/src/keas/build/package.py (rev 0)
+++ keas.build/trunk/src/keas/build/package.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,329 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Package Builder
+
+$Id$
+"""
+__docformat__ = 'ReStructuredText'
+import BeautifulSoup
+import ConfigParser
+import base64
+import logging
+import lxml.etree
+import optparse
+import os
+import pkg_resources
+import re
+import shutil
+import sys
+import tempfile
+import urllib
+import urllib2
+from keas.build import base
+
+logger = base.logger
+
+class PackageBuilder(object):
+
+ pkg = None
+ customPath = None
+ options = None
+
+ packageIndexUrl = None
+ packageIndexUsername = None
+ packageIndexPassword = None
+
+ svnRepositoryUrl = None
+ svnRepositoryUsername = None
+ svnRepositoryPassword = None
+
+ def __init__(self, pkg, options):
+ self.pkg = pkg
+ self.options = options
+
+ def getTagURL(self, version):
+ reposUrl = self.svnRepositoryUrl
+ if self.customPath:
+ reposUrl = urllib.basejoin(reposUrl, self.customPath)
+ tagUrl = reposUrl.split('%s')[0] + 'tags/%s-%s' %(self.pkg, version)
+ else:
+ tagUrl = reposUrl + 'tags/%s-%s' %(self.pkg, version)
+ logger.debug('Tag URL: ' + tagUrl)
+ return tagUrl
+
+ def getBranchURL(self, branch):
+ reposUrl = self.svnRepositoryUrl
+ if self.customPath:
+ reposUrl = urllib.basejoin(reposUrl, self.customPath)
+ branchUrl = reposUrl %('branches/' + branch)
+ if branch == 'trunk':
+ branchUrl = reposUrl %branch
+ else:
+ branchUrl = reposUrl + 'branches/' + branch + '/' + self.pkg + '/'
+ if branch == 'trunk':
+ branchUrl = reposUrl + 'trunk/' + self.pkg
+ logger.debug('Branch URL: ' + branchUrl)
+ return branchUrl
+
+ def getRevision(self, url):
+ xml = base.do('svn info --xml ' + url)
+ elem = lxml.etree.fromstring(xml)
+ revision = elem.xpath('/info/entry/commit/@revision')
+ if not revision:
+ revision = 0
+ else:
+ revision = int(revision[0])
+ logger.debug('Revision for %s: %i' %(url, revision))
+ return revision
+
+ def findVersions(self):
+ if self.options.offline:
+ logger.info('Offline: Skip looking for versions.')
+ return []
+ logger.debug('Package Index: ' + self.packageIndexUrl)
+ req = urllib2.Request(self.packageIndexUrl)
+
+ if self.packageIndexUsername:
+ base64string = base64.encodestring(
+ '%s:%s' % (self.packageIndexUsername,
+ self.packageIndexPassword))[:-1]
+ req.add_header("Authorization", "Basic %s" % base64string)
+
+ soup = BeautifulSoup.BeautifulSoup(urllib2.urlopen(req).read())
+ versions = [tag.contents[0][len(self.pkg)+1:-7]
+ for tag in soup('a')
+ if tag.contents[0].startswith(self.pkg)]
+ logger.debug('All versions: ' + ' '.join(versions))
+
+ # filter versions by ones that came from the branch we are building from.
+ if self.options.branch and '-' in self.options.branch:
+ branchVersion = self.options.branch.split('-')[-1]
+ branchVersionParts = pkg_resources.parse_version(branchVersion)[:-1]
+ def fromBranch(v):
+ versionParts = pkg_resources.parse_version(v)
+ return versionParts[:len(branchVersionParts)] == branchVersionParts
+ versions = filter(fromBranch, versions)
+ return sorted(versions, key=lambda x: pkg_resources.parse_version(x))
+
+ def getBranches(self):
+ if self.options.offline:
+ logger.info('Offline: Skip looking for branches.')
+ return []
+ url = self.svnRepositoryUrl
+ if self.customPath:
+ url = urllib.basejoin(url, self.customPath.split('%s')[0])
+ url += 'branches'
+ logger.debug('Branches URL: ' + url)
+ req = urllib2.Request(url)
+
+ if self.svnRepositoryUsername:
+ base64string = base64.encodestring('%s:%s' % (
+ self.svnRepositoryUsername, self.svnRepositoryPassword))[:-1]
+ req.add_header("Authorization", "Basic %s" % base64string)
+
+ soup = BeautifulSoup.BeautifulSoup(urllib2.urlopen(req).read())
+ branches = [tag.contents[0][:-1]
+ for tag in soup('ul')[0]('a')
+ if tag.contents[0] != '..']
+ logger.debug('Branches: ' + ' '.join(branches))
+ return branches
+
+ def hasChangedSince(self, version, branch):
+ # setup.py gets changed on the branch after the tag is created, so
+ # that the branch always has a later revision. So let's check the
+ # source directory instead.
+ branchUrl = self.getBranchURL(branch) + '/src'
+ tagUrl = self.getTagURL(version)
+ changed = self.getRevision(branchUrl) > self.getRevision(tagUrl)
+ if changed:
+ logger.info(
+ 'Branch %r changed since the release of version %s' %(
+ branch, version))
+ return changed
+
+ def createRelease(self, version, branch):
+ logger.info('Creating release %r for %r from branch %r' %(
+ version, self.pkg, branch))
+ # 0. Skip creating releases in offline mode.
+ if self.options.offline:
+ logger.info('Offline: Skip creating a release.')
+ return
+ # 1. Create Release Tag
+ branchUrl = self.getBranchURL(branch)
+ tagUrl = self.getTagURL(version)
+
+ base.do('svn cp -m "Create release tag" %s %s' %(branchUrl, tagUrl))
+
+ # 2. Download tag
+ buildDir = tempfile.mkdtemp()
+ tagDir = os.path.join(buildDir, '%s-%s' %(self.pkg, version))
+ base.do('svn co %s %s' %(tagUrl, tagDir))
+
+ # 3. Create release
+ # 3.1. Remove setup.cfg
+ setupCfgPath = os.path.join(tagDir, 'setup.cfg')
+ if os.path.exists(setupCfgPath):
+ os.remove(setupCfgPath)
+ # 3.2. Update the version
+ setuppy = file(os.path.join(tagDir, 'setup.py'), 'r').read()
+ setuppy = re.sub(
+ "version ?= ?'(.*)',", "version = '%s'," %version, setuppy)
+ file(os.path.join(tagDir, 'setup.py'), 'w').write(setuppy)
+ # 3.3. Check it all in
+ base.do('svn ci -m "Prepare for release." %s' %(tagDir))
+ # 3.4. Create distribution
+ base.do('cd %s && python setup.py sdist' %(tagDir))
+
+ # 4. Upload the distribution
+ distributionFileName = os.path.join(
+ tagDir, 'dist', '%s-%s.tar.gz' %(self.pkg, version))
+ if not self.options.noUpload:
+ base.uploadFile(
+ distributionFileName,
+ self.packageIndexUrl,
+ self.packageIndexUsername, self.packageIndexPassword,
+ self.options.offline)
+
+ # 5. Update the start branch to the next devel version
+ if not self.options.noBranchUpdate:
+ # 5.1. Check out the branch.
+ branchDir = os.path.join(buildDir, 'branch')
+ base.do('svn co %s %s' %(branchUrl, branchDir))
+ # 5.2. Get the current version.
+ setuppy = file(os.path.join(branchDir, 'setup.py'), 'r').read()
+ currVersion = re.search("version ?= ?'(.*)',", setuppy).groups()[0]
+ # 5.3. Update setup/py to the next version of the currently
+ # released one
+ newVersion = base.guessNextVersion(version) + 'dev'
+ setuppy = re.sub(
+ "version ?= ?'(.*)',", "version = '%s'," %newVersion, setuppy)
+ file(os.path.join(branchDir, 'setup.py'), 'w').write(setuppy)
+ # 5.4. Check in the changes.
+ base.do('svn ci -m "Update version number." %s' %(branchDir))
+
+ # 6. Cleanup
+ shutil.rmtree(buildDir)
+
+ def runCLI(self, configFile, askToCreateRelease=False):
+ logger.info('Start releasing new version of ' + self.pkg)
+ # 1. Read the configuration file.
+ logger.info('Loading configuration file: ' + configFile)
+ config = ConfigParser.RawConfigParser()
+ config.read(configFile)
+ # 1.1. Get package index info.
+ self.packageIndexUrl = config.get(
+ base.BUILD_SECTION, 'package-index')
+ self.packageIndexUsername = config.get(
+ base.BUILD_SECTION, 'package-index-username')
+ self.packageIndexPassword = config.get(
+ base.BUILD_SECTION, 'package-index-password')
+ # 1.2. Get svn repository info.
+ self.svnRepositoryUrl = config.get(
+ base.BUILD_SECTION, 'svn-repos')
+ self.svnRepositoryUsername = config.get(
+ base.BUILD_SECTION, 'svn-repos-username')
+ self.svnRepositoryPassword = config.get(
+ base.BUILD_SECTION, 'svn-repos-password')
+ # 1.3. Determine the possibly custom path.
+ for pkg in config.get(base.BUILD_SECTION, 'packages').split():
+ if pkg.startswith(self.pkg):
+ if ':' in pkg:
+ self.customPath = pkg.split(':')[1]
+ break
+ # 2. Find all versions.
+ versions = self.findVersions()
+ logger.info('Existing %s versions: %s' % (
+ self.pkg, ' | '.join(reversed(versions))))
+ # 3. Determine the default version to suggest.
+ defaultVersion = None
+ if versions:
+ # 3.1. If the branch was specified, check whether it changed since
+ # the last release.
+ changed = False
+ if self.options.branch:
+ changed = self.hasChangedSince(
+ versions[-1], self.options.branch)
+ # 3.2. If the branch changed and the next version should be
+ # suggested, let's find the next version.
+ if self.options.nextVersion and changed:
+ defaultVersion = base.guessNextVersion(versions[-1])
+ else:
+ defaultVersion = versions[-1]
+ while True:
+ version = base.getInput(
+ 'Version for `%s`' %self.pkg, defaultVersion,
+ self.options.useDefaults and defaultVersion is not None)
+ if version not in versions and not self.options.offline:
+ if askToCreateRelease:
+ print 'The release %s-%s does not exist.' %(pkg, version)
+ doRelease = base.getInput(
+ 'Do you want to create it? yes/no', 'yes',
+ self.options.useDefaults)
+ if doRelease == 'no':
+ continue
+ # 4. Now create a release for this version.
+ if not self.options.offline:
+ # 4.1. Determine the branch from which to base the release
+ # on.
+ branch = self.options.branch
+ if branch is None:
+ print 'Available Branches:'
+ for branch in self.getBranches():
+ print ' * ' + branch
+ print ' * trunk'
+ branch = base.getInput(
+ 'What branch do you want to use?', 'trunk',
+ self.options.useDefaults)
+ # 4.2. Create the release.
+ self.createRelease(version, branch)
+ break
+ # 5. Return the version number.
+ logger.info('Chosen version: ' + version)
+ return version
+
+
+def main(args=None):
+ # Make sure we get the arguments.
+ if args is None:
+ args = sys.argv[1:]
+ if not args:
+ args = ['-h']
+
+ # Set up logger handler
+ handler = logging.StreamHandler(sys.stdout)
+ handler.setFormatter(base.formatter)
+ logger.addHandler(handler)
+
+ # Parse arguments
+ options, args = base.parser.parse_args(args)
+
+ logger.setLevel(logging.INFO)
+ if options.verbose:
+ logger.setLevel(logging.DEBUG)
+ if options.quiet:
+ logger.setLevel(logging.FATAL)
+
+ if len(args) == 0:
+ print "No package was specified."
+ print "Usage: build-package [options] package1 package2 ..."
+ sys.exit(0)
+ for pkg in args:
+ builder = PackageBuilder(pkg, options)
+ builder.runCLI(options.configFile)
+
+ # Remove the handler again.
+ logger.removeHandler(handler)
+
+ # Exit cleanly.
+ sys.exit(0)
Property changes on: keas.build/trunk/src/keas/build/package.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/sample/buildout.cfg
===================================================================
--- keas.build/trunk/src/keas/build/sample/buildout.cfg (rev 0)
+++ keas.build/trunk/src/keas/build/sample/buildout.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,10 @@
+[buildout]
+develop = .
+parts = build-moo-project
+
+[build-moo-project]
+recipe = zc.recipe.egg
+eggs = keas.build
+scripts = build=build-moo-project
+initialization =
+ sys.argv[1:1] = ['-c', 'moo/moo-Project-Build.cfg']
\ No newline at end of file
Property changes on: keas.build/trunk/src/keas/build/sample/buildout.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/sample/moo/Deploy.cfg
===================================================================
--- keas.build/trunk/src/keas/build/sample/moo/Deploy.cfg (rev 0)
+++ keas.build/trunk/src/keas/build/sample/moo/Deploy.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,18 @@
+[server-1]
+server = server-1.foobar.com
+username = username
+password = password
+commands =
+ /opt/moo/bin/moo stop
+ /usr/bin/install-moo-dev -l
+ /opt/moo/bin/moo start
+
+[server-2]
+server = server-2.foobar.com
+username = admin
+password = password
+commands =
+ /opt/moo/bin/moo stop
+ /usr/bin/install-moo-release -l
+ /opt/moo/bin/moo start
+
Property changes on: keas.build/trunk/src/keas/build/sample/moo/Deploy.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/sample/moo/Installers.cfg
===================================================================
--- keas.build/trunk/src/keas/build/sample/moo/Installers.cfg (rev 0)
+++ keas.build/trunk/src/keas/build/sample/moo/Installers.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,31 @@
+[buildout]
+extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+parts = install-moo-dev install-moo-release
+directory = /opt/moo/install
+extensions = lovely.buildouthttp
+find-links = http://eggs.foobar.com
+versions = versions
+
+[buildout-bin]
+recipe = zc.recipe.egg
+eggs = zc.buildout
+scripts = buildout
+
+[install-moo-dev]
+recipe = zc.recipe.egg
+eggs = keas.build
+scripts = install=install-moo-dev
+initialization =
+ sys.argv[1:1] = ['-u', 'http://eggs.foobar.com/',
+ '--username', 'username', '--password', 'password',
+ '-p', 'moo', '-V', 'Development']
+
+
+[install-moo-release]
+recipe = zc.recipe.egg
+eggs = keas.build
+scripts = install=install-moo-release
+initialization =
+ sys.argv[1:1] = ['-u', 'http://eggs.foobar.com/',
+ '--username', 'username', '--password', 'password',
+ '-p', 'moo', '-V', 'Release']
Property changes on: keas.build/trunk/src/keas/build/sample/moo/Installers.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/sample/moo/moo-Instance-Template.cfg
===================================================================
--- keas.build/trunk/src/keas/build/sample/moo/moo-Instance-Template.cfg (rev 0)
+++ keas.build/trunk/src/keas/build/sample/moo/moo-Instance-Template.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,42 @@
+[buildout]
+parts += moo
+directory = %(install-dir)s
+
+[database]
+recipe = zc.recipe.filestorage
+
+[moo]
+recipe = zc.zope3recipes:instance
+application = moo-app
+zope.conf =
+ <zodb>
+ cache-size 20000
+ <filestorage>
+ path ${database:path}
+ create true
+ </filestorage>
+ </zodb>
+
+ <server>
+ type WSGI-HTTP
+ address %(port)s
+ </server>
+
+ <eventlog>
+ level %(loglevel)s
+ <logfile>
+ formatter zope.exceptions.log.Formatter
+ path %(logdir)s/moo.log
+ max-size 50MB
+ old-files 5
+ </logfile>
+ </eventlog>
+
+ <accesslog>
+ <logfile>
+ level info
+ path %(logdir)s/moo-access.log
+ max-size 50MB
+ old-files 5
+ </logfile>
+ </accesslog>
Property changes on: keas.build/trunk/src/keas/build/sample/moo/moo-Instance-Template.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/sample/moo/moo-Project-Build.cfg
===================================================================
--- keas.build/trunk/src/keas/build/sample/moo/moo-Project-Build.cfg (rev 0)
+++ keas.build/trunk/src/keas/build/sample/moo/moo-Project-Build.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,31 @@
+[build]
+name = moo
+version = +
+template = moo/moo-Release-Template.cfg
+package-index = https://eggs.foobar.com/
+package-index-username = username
+package-index-password = password
+buildout-server = https://eggs.foobar.com/
+buildout-server-username = username
+buildout-server-password = password
+svn-repos = https://svn.zope.org/svn/
+svn-repos-username = username
+svn-repos-password = password
+packages = moo.base
+ moo.skin
+ moo.razor
+ moo.app
+
+[Development]
+template = moo/moo-Instance-Template.cfg
+port = 8080
+logdir = /var/log/moo
+install-dir = /opt/moo
+loglevel = debug
+
+[Release]
+template = moo/moo-Instance-Template.cfg
+port = 8081
+logdir = /var/log/moo
+install-dir = /opt/moo
+loglevel = warn
\ No newline at end of file
Property changes on: keas.build/trunk/src/keas/build/sample/moo/moo-Project-Build.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/sample/moo/moo-Release-Template.cfg
===================================================================
--- keas.build/trunk/src/keas/build/sample/moo/moo-Release-Template.cfg (rev 0)
+++ keas.build/trunk/src/keas/build/sample/moo/moo-Release-Template.cfg 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,39 @@
+[buildout]
+extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+parts = test coverage-test coverage-report python
+extensions = lovely.buildouthttp
+find-links = http://eggs.foobar.com/
+versions = versions
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = moo.app
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = moo.app
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
+
+[python]
+recipe = zc.recipe.egg
+interpreter = python
+eggs = moo.app
+
+[moo-app]
+recipe = zc.zope3recipes:app
+servers = zserver
+site.zcml = <include package="moo.app" file="app.zcml" />
+eggs = moo.app
+
+[zope3]
+location =
+
+[versions]
+lxml = 2.1.2
+mechanize = 0.1.8
Property changes on: keas.build/trunk/src/keas/build/sample/moo/moo-Release-Template.cfg
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
Added: keas.build/trunk/src/keas/build/ssh.py
===================================================================
--- keas.build/trunk/src/keas/build/ssh.py (rev 0)
+++ keas.build/trunk/src/keas/build/ssh.py 2009-08-11 08:54:50 UTC (rev 102652)
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""SSH tools
+
+$Id$
+"""
+import StringIO
+import logging
+import sys
+from twisted.conch.ssh import transport, userauth, connection, channel
+from twisted.conch.ssh.common import NS
+from twisted.internet import defer, protocol, reactor
+from keas.build import base
+
+class Transport(transport.SSHClientTransport):
+ user = None
+ password = None
+ cmd = None
+ output = None
+
+ def verifyHostKey(self, hostKey, fingerprint):
+ base.logger.debug('host key fingerprint: %s' % fingerprint)
+ return defer.succeed(1)
+
+ def connectionSecure(self):
+ conn = Connection()
+ conn.cmd = self.cmd
+ conn.output = self.output
+ self.requestService(UserAuth(self.user, self.password, conn))
+
+
+class UserAuth(userauth.SSHUserAuthClient):
+
+ def __init__(self, user, password, instance):
+ userauth.SSHUserAuthClient.__init__(self, user, instance)
+ self.password = password
+
+ def getPassword(self):
+ return defer.succeed(self.password)
+
+ def getPublicKey(self):
+ return # Empty implementation: always use password auth
+
+
+class Connection(connection.SSHConnection):
+ cmd = None
+
+ def serviceStarted(self):
+ channel = Channel(2**16, 2**15, self)
+ channel.cmd = self.cmd
+ channel.output = self.output
+ self.openChannel(channel)
+
+
+class Channel(channel.SSHChannel):
+ name = 'session' # must use this exact string
+ cmd = None
+ output = None
+
+ def openFailed(self, reason):
+ base.logger.error('"%s" failed: %s' % (self.cmd, reason))
+
+ def channelOpen(self, data):
+ self.welcome = data # Might display/process welcome screen
+ d = self.conn.sendRequest(self, 'exec', NS(self.cmd), wantReply=1)
+
+ def dataReceived(self, data):
+ self.output.write(data)
+
+ def extReceived(self, dataType, data):
+ self.output.write(data)
+
+ def closed(self):
+ self.loseConnection()
+ reactor.stop()
+
+
+def run(cmd, host, username, password):
+ handler = logging.StreamHandler(sys.stdout)
+ handler.setFormatter(base.formatter)
+ base.logger.addHandler(handler)
+
+ output = StringIO.StringIO()
+ def createTransport(*args, **kwargs):
+ transport = Transport(*args, **kwargs)
+ transport.user = username
+ transport.password = password
+ transport.cmd = cmd
+ transport.output = output
+ return transport
+ protocol.ClientCreator(reactor, createTransport).connectTCP(host, 22)
+ reactor.run()
+
+ base.logger.removeHandler(handler)
+
+ return output.getvalue()
+
+if __name__ == '__main__':
+ print run(*sys.argv[1:])
Property changes on: keas.build/trunk/src/keas/build/ssh.py
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision
Added: svn:eol-style
+ native
More information about the Checkins
mailing list