#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.


# the following two variables are used by the target "waf dist"
# if you change 'em here, you need to change it also in cloud.spec, add a %changelog entry there, and add an entry in debian/changelog
VERSION = '3.0.3.2012-05-15T19:32:03Z'

APPNAME = 'cloud'

import shutil,os
import email,time
import optparse
import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure
from subprocess import Popen as _Popen,PIPE
import os
import sys
from os import unlink as _unlink, makedirs as _makedirs, getcwd as _getcwd, chdir as _chdir
from os.path import abspath as _abspath, basename as _basename, dirname as _dirname, exists as _exists, isdir as _isdir, split as _split, join as _join, sep, pathsep, pardir, curdir
from glob import glob as _glob
import zipfile,tarfile
try:
  from os import chmod as _chmod,chown as _chown
  import pwd,stat,grp
except ImportError:
  _chmod,_chown,pwd,stat,grp = (None,None,None,None,None)
import xml.dom.minidom
import re

# these variables are mandatory ('/' are converted automatically)
srcdir = '.'
blddir = 'artifacts'

Configure.autoconfig = True

# things not to include in the source tarball
# exclude by file name or by _glob (wildcard matching)
for _globber in [
	["dist",    # does not belong in the source tarball
	"system",  # for windows
	"override",  # not needed
	"eclipse", # only there to please eclipse
	"repomanagement",  # internal management stuff
	"client-api",  # obsolete
	"cloud-bridge",  # not compiled and packaged yet
	"target",  # eclipse workdir
        "apache-log4j-1.2.16",
        "apache-log4j-extras-1.1",
        "cglib",
        "gson",
        "ehcache",
        "vhd-tools",
        "xmlrpc",
        "PreviousDatabaseSchema",
        "mockito",
        "gcc",
        "junit" ],
	_glob("./*.disabledblahxml"),
	]:
	for f in _globber: Scripting.excludes.append(_basename(f)) # _basename() only the filename

# things never to consider when building or installing
for pattern in ["**/.project","**/.classpath","**/.pydevproject"]: Node.exclude_regs += "\n%s"%pattern

# Support functions

def inspectobj(x):
	"""Look inside an object"""
	for m in dir(x): print m,":	",getattr(x,m)
Utils.inspectobj = inspectobj

def _trm(x,y):
	if len(x) > y: return x[:y] + "..."
	return x

def getrpmdeps():
	def rpmdeps(fileset):
		for f in fileset:
			lines = file(f).readlines()
			lines = [ x[len("BuildRequires: "):] for x in lines if x.startswith("BuildRequires") ]
			for l in lines:
				deps = [ x.strip() for x in l.split(",") ]
				for d in deps:
					if "%s-"%APPNAME in d: continue
					yield d
		yield "rpm-build"

	deps = set(rpmdeps(_glob("./*.spec")))
	return deps

def getdebdeps():
	def debdeps(fileset):
		for f in fileset:
			lines = file(f).readlines()
			lines = [ x[len("Build-Depends: "):] for x in lines if x.startswith("Build-Depends") ]
			for l in lines:
				deps = [ x.strip() for x in l.split(",") ]
				for d in deps:
					if "%s-"%APPNAME in d: continue
					yield d
		yield "build-essential"
		yield "devscripts"
		yield "debhelper"

	deps = set(debdeps(["debian/control"]))
	return deps

# CENTOS does not have this -- we have to put this here
try:
	from subprocess import check_call as _check_call
	from subprocess import CalledProcessError
except ImportError:
	def _check_call(*popenargs, **kwargs):
		import subprocess
		retcode = subprocess.call(*popenargs, **kwargs)
		cmd = kwargs.get("args")
		if cmd is None: cmd = popenargs[0]
		if retcode: raise CalledProcessError(retcode, cmd)
		return retcode

	class CalledProcessError(Exception):
		def __init__(self, returncode, cmd):
			self.returncode = returncode ; self.cmd = cmd
		def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
def throws_command_errors(f):
	def g(*args,**kwargs):
		try: return f(*args,**kwargs)
		except CalledProcessError,e:
			raise Utils.WafError("system command %s failed with error value %s"%(e.cmd[0],e.returncode))
		except IOError,e:
			if e.errno is 32:
				raise Utils.WafError("system command %s terminated abruptly, closing communications with parent's pipe"%e.cmd[0])
			raise
	return g

def c(cmdlist,cwd=None):
	# Run a command with _check_call, pretty-printing the cmd list
	Utils.pprint("BLUE"," ".join(cmdlist))
	return _check_call(cmdlist,cwd=cwd)

def svninfo(*args):
	try: p = _Popen(['svn','info']+list(args),stdin=PIPE,stdout=PIPE,stderr=PIPE)
	except OSError,e:
		if e.errno == 2: return '' # svn command is not installed
		raise
	stdout,stderr = p.communicate('')
	retcode = p.wait()
	# If the guess fails, just return nothing.
	if retcode: return
	# SVN available
	rev = [ x for x in stdout.splitlines() if x.startswith('Revision') ]
	if not rev: rev = ''
	else: rev = "SVN " + rev[0].strip()
	url = [ x for x in stdout.splitlines() if x.startswith('URL') ]
	if not url: url = ''
	else: url = "SVN " + url[0].strip()
	return rev + "\n" + url

def gitinfo(dir=None):
	if dir and not _isdir(dir): return ''
	try: p = _Popen(['git','remote','show','-n','origin'],stdin=PIPE,stdout=PIPE,stderr=PIPE,cwd=dir)
	except OSError,e:
		if e.errno == 2: return '' # svn command is not installed
		raise
	stdout,stderr = p.communicate('')
	retcode = p.wait()
	# If the guess fails, just return nothing.
	if retcode: return
	stdout = [ s.strip() for s in stdout.splitlines() ]
	try: url = [ s[11:] for s in stdout if s.startswith("Fetch URL") ][0]
	except IndexError: url = [ s[5:] for s in stdout if s.startswith("URL") ][0]
	assert url
	
	p = _Popen(['git','log','-1'],stdin=PIPE,stdout=PIPE,stderr=PIPE,cwd=dir)
	stdout,stderr = p.communicate('')
	retcode = p.wait()
	if retcode: return
	# If the guess fails, just return nothing.
	stdout = [ s.strip() for s in stdout.splitlines() ]
	commitid = [ s.split()[1] for s in stdout if s.startswith("commit") ][0]
	assert commitid
	
	return "Git Revision: %s"%commitid + "\n" + "Git URL: %s"%url

def allgitinfo():
	t = gitinfo()
	if not t: return t
	
	u = gitinfo(_join(pardir,"cloudstack-proprietary"))
	if not u: return t
	
	return t + "\n\ncloustack-proprietary:\n" + u

def _getbuildnumber(): # FIXME implement for git
	n = Options.options.BUILDNUMBER
	if n:
		# luntbuild prepends "build-" to the build number.  we work around this here:
		if n.startswith("build-"): n = n[6:]
		# SVN identifiers prepend "$Revision:" to the build number.  we work around this here:
		if n.startswith("$Revision:"): n = n[11:-2].strip()
		return n
	else:
		# Try to guess the SVN revision number by calling SVN info.
		stdout = svninfo()
		if not stdout: return ''
		# Filter lines.
		rev = [ x for x in stdout.splitlines() if x.startswith('SVN Revision') ]
		if not rev: return ''
		# Parse revision number.
		rev = rev[0][14:].strip()
		return rev
Utils.getbuildnumber = _getbuildnumber

def mkdir_p(directory):
	if not _isdir(directory):
		Utils.pprint("GREEN","Creating directory %s and necessary parents"%directory)
		_makedirs(directory)

def relpath(path, start="."):
    if not path: raise ValueError("no path specified")

    start_list = os.path.abspath(start).split(sep)
    path_list = os.path.abspath(path).split(sep)

    # Work out how much of the filepath is shared by start and path.
    i = len(os.path.commonprefix([start_list, path_list]))

    rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
    if not rel_list:
        return curdir
    return os.path.join(*rel_list)
Utils.relpath = relpath

def dev_override(pathname):
	p,e = _split(pathname)
	overridden = _join(p,"override",e)
	if _exists(overridden): return overridden
	return pathname

def discover_ant_targets_and_properties(files):
	doms = [ xml.dom.minidom.parseString(file(f).read(-1)) for f in files if f.endswith(".xml") ]
	targets = dict( [ (target.getAttribute("name"),target) for dom in doms for target in dom.getElementsByTagName("target") if target.getElementsByTagName("compile-java") ] )
	propsinxml = [ (prop.getAttribute("name"),prop.getAttribute("value") or prop.getAttribute("location")) for dom in doms for prop in dom.getElementsByTagName("property") ]
	propsinpropfiles = [ l.strip().split("=",1) for f in files if f.endswith(".properties") for l in file(f).readlines() if "=" in l and not l.startswith("#") ]
	props = dict( propsinxml + propsinpropfiles )
	props["base.dir"] = '.'
	props["p.base.dir"] = '.'

	result = []
	for name,target in targets.items():
		sourcedir = target.getElementsByTagName("compile-java")[0].getAttribute("top.dir") + "/src"
		classdir = "${classes.dir}/" + target.getElementsByTagName("compile-java")[0].getAttribute("jar.name")
		jarpath = "${jar.dir}/" + target.getElementsByTagName("compile-java")[0].getAttribute("jar.name")
		def lookup(matchobject): return props[matchobject.group(1)]
		while "$" in sourcedir: sourcedir = re.sub("\${(.+?)}",lookup,sourcedir)
		while "$" in classdir:  classdir = re.sub("\${(.+?)}",lookup,classdir)
		while "$" in jarpath:   jarpath= re.sub("\${(.+?)}",lookup,jarpath)
		dependencies = [ dep.strip() for dep in target.getAttribute("depends").split(",") if dep.strip() in targets ]
		result.append([str(name),str(relpath(sourcedir)),str(relpath(classdir)),str(relpath(jarpath)),[str(s) for s in dependencies]])
	# hardcoded here because the discovery process does not get it
	result.append( ["build-console-viewer","console-viewer/src", "target/classes/console-viewer", "target/jar/VMOpsConsoleApplet.jar", ["compile-utils","compile-console-common"] ] )
	return result,props
Utils.discover_ant_targets_and_properties = discover_ant_targets_and_properties

# this snippet of code runs a list of ant targets
# then it expects a certain set of JAR files to be output in the artifacts/default/ant/jar directory
# this set of jar files is defined here in the variable jartgts, and must match the definitions at the bottom of
# build/package.xml and build/premium/package-premium.xml
# this is NOT a task for a task generator -- it is a plain function.
# If you want to use it as a task function in a task generator, use a lambda x: runant("targetname")
def runant(tsk):
	environ = dict(os.environ)
	environ["CATALINA_HOME"] = tsk.env.TOMCATHOME
	environ["ANT_HOME"] = _join("tools","ant","apache-ant-1.7.1")
	if tsk.generator.env.DISTRO == "Windows":
		stanzas = [
			_join(environ["ANT_HOME"],"bin","ant.bat"),
			"-Dthirdparty.classpath=\"%s\""%(tsk.env.CLASSPATH.replace(os.pathsep,",")),
		]
	else:
		stanzas = [
			_join(environ["ANT_HOME"],"bin","ant"),
			"-Dthirdparty.classpath=%s"%(tsk.env.CLASSPATH.replace(os.pathsep,",")),
		]
	stanzas += tsk.generator.antargs
	ret = Utils.exec_command(" ".join(stanzas),cwd=tsk.generator.bld.srcnode.abspath(),env=environ,log=True)
	if ret != 0: raise Utils.WafError("Ant command %s failed with error value %s"%(stanzas,ret))
	return ret
Utils.runant = runant

@throws_command_errors
def run_java(classname,classpath,options=None,arguments=None):
	if not options: options = []
	if not arguments: arguments = []
	if type(classpath) in [list,tuple]: classpath = pathsep.join(classpath)
	
	Utils.pprint("BLUE","Run-time CLASSPATH:")
	for v in classpath.split(pathsep): Utils.pprint("BLUE","     %s"%v)

	cmd = ["java","-classpath",classpath] + options + [classname] + arguments
	Utils.pprint("BLUE"," ".join([ _trm(x,32) for x in cmd ]))
	_check_call(cmd)

# this will enforce the after= ordering constraints in the javac task generators
from TaskGen import after, feature
@feature('*')
@after('apply_core', 'apply_java', 'apply_subst')
def process_after(self):
	lst = self.to_list(getattr(self, 'after', []))
	for x in lst:
		obj = self.bld.name_to_obj(x,self.bld.env)
		if not obj: break
		obj.post()
		for a in obj.tasks:
			for b in self.tasks:
				b.set_run_after(a)

Build.BuildContext.process_after = staticmethod(process_after)

def _getbuildcontext():
	ctx = Build.BuildContext()
	ctx.load_dirs(_abspath(srcdir),_abspath(blddir))
	ctx.load_envs()
	return ctx

def _install_files_filtered(self,destdir,listoffiles,**kwargs):
	if "cwd" in kwargs: cwd = kwargs["cwd"]
	else: cwd = self.path
	if isinstance(listoffiles,str) and '**' in listoffiles:
		listoffiles = cwd.ant_glob(listoffiles,flat=True)
	elif isinstance(listoffiles,str) and '*' in listoffiles:
		listoffiles = [ n for x in listoffiles.split() for n in _glob(cwd.abspath() + os.sep + x.replace("/",os.sep))  ]
	listoffiles = Utils.to_list(listoffiles)[:]
	listoffiles = [ x for x in listoffiles if not ( x.endswith("~") or x == "override" or "%soverride"%os.sep in x ) ]
	for n,f in enumerate(listoffiles):
		f = os.path.abspath(f)
		f = dev_override(f)
		if _isdir(f): continue
		if f.endswith(".in"):
			source = f ; target = f[:-3]
			tgen = self(features='subst', source=source[len(self.path.abspath())+1:], target=target[len(self.path.abspath())+1:], name="filtered_%s"%source)
			tgen.dict = self.env.get_merged_dict()
		else:
			source = f ; target = f
		listoffiles[n] = target[len(cwd.abspath())+1:]
	if "postpone" not in kwargs: kwargs["postpone"] = True
	ret = self.install_files(destdir,listoffiles,**kwargs)
	return ret
Build.BuildContext.install_files_filtered = _install_files_filtered

def _substitute(self,listoffiles,install_to=None,cwd=None,dict=None,name=None,**kwargs):
	if cwd is None: cwd = self.path
	tgenkwargs = {}
	if name is not None: tgenkwargs["name"] = name
	if isinstance(listoffiles,str) and '**' in listoffiles:
		listoffiles = cwd.ant_glob(listoffiles,flat=True)
	elif isinstance(listoffiles,str) and '*' in listoffiles:
		listoffiles = [ n for x in listoffiles.split() for n in _glob(cwd.abspath() + os.sep + x.replace("/",os.sep))  ]
	for src in Utils.to_list(listoffiles):
		tgt = src + ".subst"
		inst = src # Utils.relpath(src,relative_to) <- disabled

		# Use cwd path when creating task and shift back later
		tmp = self.path
		self.path = cwd
		tgen = self(features='subst', source=src, target=tgt, **tgenkwargs)
		self.path = tmp

		if dict is not None: tgen.dict = dict
		else: tgen.dict = self.env.get_merged_dict()
		self.path.find_or_declare(tgt)
		if install_to is not None: self.install_as("%s/%s"%(install_to,inst), tgt, cwd=cwd, **kwargs)
Build.BuildContext.substitute = _substitute

def set_options(opt):
	"""Register command line options"""
	opt.tool_options('gnu_dirs')
	opt.tool_options('python')
	opt.tool_options('tar',tooldir='tools/waf')
	opt.tool_options('mkisofs',tooldir='tools/waf')
	if Options.platform not in ['darwin','win32']: opt.tool_options('usermgmt',tooldir='tools/waf')
	if Options.platform not in ['darwin','win32']: opt.tool_options('javadir',tooldir='tools/waf')
	opt.tool_options('tomcat',tooldir='tools/waf')
	if Options.platform not in ['darwin',"win32"]: opt.tool_options('compiler_cc')
	
        inst_dir = opt.get_option_group('--srcdir')
	inst_dir.add_option('--with-db-host',
		help = 'Database host to use for waf deploydb [Default: 127.0.0.1]',
		default = '127.0.0.1',
		dest = 'DBHOST')
	inst_dir.add_option('--with-db-user',
		help = 'Database user to use for waf deploydb [Default: root]',
		default = 'root',
		dest = 'DBUSER')
	inst_dir.add_option('--with-db-pw',
		help = 'Database password to use for waf deploydb [Default: ""]',
		default = '',
		dest = 'DBPW')
	inst_dir.add_option('--tomcat-user',
		help = 'UNIX user that the management server initscript will switch to [Default: <autodetected>]',
		default = '',
		dest = 'MSUSER')
	inst_dir.add_option('--no-dep-check',
		action='store_true',
		help = 'Skip dependency check and assume JARs already exist',
		default = False,
		dest = 'NODEPCHECK')
	inst_dir.add_option('--fast',
		action='store_true',
		help = 'does ---no-dep-check',
		default = False,
		dest = 'NODEPCHECK')
        inst_dir = opt.get_option_group('--force')
	inst_dir.add_option('--preserve-config',
		action='store_true',
		help = 'do not install configuration files',
		default = False,
		dest = 'PRESERVECONFIG')

	debugopts = optparse.OptionGroup(opt.parser,'run/debug options')
	opt.add_option_group(debugopts)
	debugopts.add_option('--debug-port',
		help = 'Port on which the debugger will listen when running waf debug [Default: 8787]',
		default = '8787',
		dest = 'DEBUGPORT')
	debugopts.add_option('--debug-suspend',
		action='store_true',
		help = 'Suspend the process upon startup so that a debugger can attach and set breakpoints',
		default = False,
		dest = 'DEBUGSUSPEND')
	debugopts.add_option('--run-verbose',
		action='store_true',
		help = 'Run Tomcat in verbose mode (java option -verbose)',
		default = False,
		dest = 'RUNVERBOSE')
	
	rpmopts = optparse.OptionGroup(opt.parser,'RPM/DEB build options')
	opt.add_option_group(rpmopts)
	rpmopts.add_option('--build-number',
		help = 'Build number [Default: SVN revision number for builds from checkouts, or empty for builds from source releases]',
		default = '',
		dest = 'BUILDNUMBER')
	rpmopts.add_option('--package-version',
		help = 'package version',
		default = '',
		dest = 'VERNUM')
	rpmopts.add_option('--release-version',
		help = 'release version',
		default = '',
		dest = 'RELEASENUM')
	rpmopts.add_option('--prerelease',
		help = 'Branch name to append to the release number (if specified, alter release number to be a prerelease); this option requires --build-number=X [Default: nothing]',
		default = '',
		dest = 'PRERELEASE')
	rpmopts.add_option('--skip-dist',
		action='store_true',
		help = 'Normally, dist() is called during package build.  This makes the package build assume that a distribution tarball has already been made, and use that.  This option is also valid during distcheck and dist.',
		default = False,
		dest = 'DONTDIST')
	
	distopts = optparse.OptionGroup(opt.parser,'dist options')
	opt.add_option_group(distopts)
	distopts.add_option('--oss',
		help = 'Only include open source components',
		action = 'store_true',
		default = False,
		dest = 'OSS')

def showconfig(conf):
	"""prints out the current configure environment configuration"""
	conf = _getbuildcontext()
	
	Utils.pprint("WHITE","Build environment:")
	for key,val in sorted(conf.env.get_merged_dict().items()):
		if "CLASSPATH" in key:
			Utils.pprint("BLUE","  %s:"%key)
			for v in val.split(pathsep):
				Utils.pprint("BLUE","     %s"%v)
			continue
		Utils.pprint("BLUE","  %s:	%s"%(key,val))

def _getconfig(self):
	lines = []
	for key,val in sorted(self.env.get_merged_dict().items()):
		if "CLASSPATH" in key:
			lines.append("  %s:"%key)
			for v in val.split(pathsep):
				lines.append("     %s"%v)
			continue
		lines.append("  %s:	%s"%(key,val))
	return "\n".join(lines)
Build.BuildContext.getconfig = _getconfig

def list_targets(ctx):
        """return the list of buildable and installable targets"""

	bld = Build.BuildContext()
	proj = Environment.Environment(Options.lockfile)
	bld.load_dirs(proj['srcdir'], proj['blddir'])
	bld.load_envs()
	
	bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]])

	names = set([])
	for x in bld.all_task_gen:
		try:
			names.add(x.name or x.target)
		except AttributeError:
			pass

	lst = list(names)
	lst.sort()
	for name in lst:
		print(name)

def decorate_dist(f):
	def dist(appname='',version=''):
		'''makes a tarball for redistributing the sources -- if --skip-dist is specified, does nothing'''
		if Options.options.DONTDIST:
			if not appname: appname=Utils.g_module.APPNAME
			if not version: version=Utils.g_module.VERSION
			tmp_folder=appname+'-'+version
			if Scripting.g_gz in['gz','bz2']:
				arch_name=tmp_folder+'.tar.'+Scripting.g_gz
			else:
				arch_name=tmp_folder+'.'+'zip'
			Logs.info('New archive skipped: %s'%(arch_name))
			return arch_name
		else:
			return f(appname,version)
	return dist
Scripting.dist = decorate_dist(Scripting.dist)

def dist_hook():
	# Clean the GARBAGE that clogs our repo to the tune of 300 MB
	# so downloaders won't have to cry every time they download a "source"
	# package over 90 MB in size
	[ shutil.rmtree(f) for f in _glob(_join("*","bin")) if _isdir(f) ]
	[ shutil.rmtree(f) for f in _glob(_join("cloudstack-proprietary","thirdparty","*")) if _isdir(f) ]
	[ shutil.rmtree(f) for f in [ _join("cloudstack-proprietary","tools") ] if _isdir(f) ]
	
	if Options.options.OSS:
		[ shutil.rmtree(f) for f in "cloudstack-proprietary".split() if _exists(f) ]
		
	stdout = svninfo("..") or allgitinfo()
	if stdout:
		f = file("sccs-info","w")
		f.write(stdout)
		f.flush()
		f.close()
	else:
		# No SVN available
		if _exists("sccs-info"):
			# If the file already existed, we preserve it
			return
		else:
			f = file("sccs-info","w")
			f.write("No revision control information could be detected when the source distribution was built.")
			f.flush()
			f.close()

def bindist(ctx):
	"""creates a binary distribution that, when unzipped in the root directory of a machine, deploys the entire stack"""
	ctx = _getbuildcontext()

	if Options.options.VERNUM:
		VERSION = Options.options.VERNUM

	tarball = "%s-bindist-%s.tar.%s"%(APPNAME,VERSION,Scripting.g_gz)
	zf = _join(ctx.bldnode.abspath(),tarball)
	Options.options.destdir = _join(ctx.bldnode.abspath(),"bindist-destdir")
	Scripting.install(ctx)
	
	if _exists(zf): _unlink(zf)
	Utils.pprint("GREEN","Creating %s"%(zf))
	z = tarfile.open(zf,"w:bz2")
	cwd = _getcwd()
	_chdir(Options.options.destdir)
	z.add(".")
	z.close()
	_chdir(cwd)

@throws_command_errors
def rpm(context):
	buildnumber = Utils.getbuildnumber()
	if buildnumber: buildnumber = ["--define","_build_number %s"%buildnumber]
	else: buildnumber = []

	if Options.options.PRERELEASE:
		if not buildnumber:
			raise Utils.WafError("Please specify a build number to go along with --prerelease")
		prerelease = ["--define","_prerelease %s"%Options.options.PRERELEASE]
	else: prerelease = []

	if Options.options.RELEASENUM:
		release = Options.options.RELEASENUM
	else: release = "1"
	
	releasever = ["--define", "_rel %s" % release]

	if Options.options.VERNUM:
		ver = Options.options.VERNUM
	else: ver = "2.2"

	packagever = ["--define", "_ver %s" % ver]
	
	# FIXME wrap the source tarball in POSIX locking!
	if not Options.options.blddir: outputdir = _join(context.curdir,blddir,"rpmbuild")
	else:			   outputdir = _join(_abspath(Options.options.blddir),"rpmbuild")
	Utils.pprint("GREEN","Building RPMs")

	tarball = Scripting.dist('', ver)
	sourcedir = _join(outputdir,"SOURCES")
	
	if _exists(sourcedir): shutil.rmtree(sourcedir)
	for a in ["RPMS/noarch","SRPMS","BUILD","SPECS","SOURCES"]: mkdir_p(_join(outputdir,a))
	shutil.move(tarball,_join(sourcedir,tarball))

	specfile = "%s.spec"%APPNAME
	checkdeps = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"--nobuild",specfile]+packagever+releasever)
	dorpm = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"-bb",specfile]+buildnumber+prerelease+packagever+releasever)
	try: checkdeps()
	except (CalledProcessError,OSError),e:
		Utils.pprint("YELLOW","Dependencies might be missing.  Trying to auto-install them...")
		installrpmdeps(context)
	dorpm()

@throws_command_errors
def deb(context):
	buildnumber = Utils.getbuildnumber()
	if buildnumber: buildnumber = ["--set-envvar=BUILDNUMBER=%s"%buildnumber]
	else: buildnumber = []
	
	if Options.options.VERNUM:
		VERSION = Options.options.VERNUM
	else:
		VERSION = "2.2"

	version = ["--set-envvar=PACKAGEVERSION=%s"%VERSION]

	if Options.options.PRERELEASE:
		if not buildnumber:
			raise Utils.WafError("Please specify a build number to go along with --prerelease")
		# version/release numbers are read by dpkg-buildpackage from line 1 of debian/changelog
		# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version
		tempchangelog = """%s (%s-~%s%s) unstable; urgency=low

  * Automatic prerelease build

 -- Automated build system <noreply@cloud.com>  %s"""%(
			APPNAME,
			VERSION,
			Utils.getbuildnumber(),
			Options.options.PRERELEASE,
			email.Utils.formatdate(time.time())
		)
	else:
		tempchangelog = """%s (%s-1) stable; urgency=low

  * Automatic release build

 -- Automated build system <noreply@cloud.com>  %s"""%(
			APPNAME,
			VERSION,
			email.Utils.formatdate(time.time())
		)
	
	# FIXME wrap the source tarball in POSIX locking!
	if not Options.options.blddir: outputdir = _join(context.curdir,blddir,"debbuild")
	else:			   outputdir = _join(_abspath(Options.options.blddir),"debbuild")
	Utils.pprint("GREEN","Building DEBs")

	tarball = Scripting.dist('', VERSION)	
	srcdir = "%s/%s-%s"%(outputdir,APPNAME,VERSION)

	if _exists(srcdir): shutil.rmtree(srcdir)
	mkdir_p(outputdir)

	f = tarfile.open(tarball,'r:bz2')
	f.extractall(path=outputdir)
	if tempchangelog:
		f = file(_join(srcdir,"debian","changelog"),"w")
		f.write(tempchangelog)
		f.flush()
		f.close()
	
	checkdeps = lambda: c(["dpkg-checkbuilddeps"],srcdir)
	dodeb = lambda: c(["debuild",'-e','WAFCACHE','--no-lintian', '--no-tgz-check']+buildnumber+version+["-us","-uc"],srcdir)
	try: checkdeps()
	except (CalledProcessError,OSError),e:
		Utils.pprint("YELLOW","Dependencies might be missing.  Trying to auto-install them...")
		installdebdeps(context)
	dodeb()

def uninstallrpms(context):
	"""uninstalls any Cloud Stack RPMs on this system"""
	Utils.pprint("GREEN","Uninstalling any installed RPMs")
	cmd = "rpm -qa | grep %s- | xargs -r sudo rpm -e"%APPNAME
	Utils.pprint("BLUE",cmd)
	system(cmd)

def uninstalldebs(context):
	"""uninstalls any Cloud Stack DEBs on this system"""
	Utils.pprint("GREEN","Uninstalling any installed DEBs")
	cmd = "dpkg -l '%s-*' | grep ^i | awk '{ print $2 } ' | xargs aptitude purge -y"%APPNAME
	Utils.pprint("BLUE",cmd)
	system(cmd)

def viewrpmdeps(context):
	"""shows all the necessary dependencies to build the RPM packages of the stack"""
	for dep in getrpmdeps(): print dep

def viewdebdeps(context):
	"""shows all the necessary dependencies to build the DEB packages of the stack"""
	for dep in getdebdeps(): print dep

@throws_command_errors
def installrpmdeps(context):
	"""installs all the necessary dependencies to build the RPM packages of the stack"""
	runnable = ["sudo","yum","install","-y"]+list(getrpmdeps())
	Utils.pprint("GREEN","Installing RPM build dependencies")
	Utils.pprint("BLUE"," ".join(runnable))
	_check_call(runnable)

@throws_command_errors
def installdebdeps(context):
	"""installs all the necessary dependencies to build the DEB packages of the stack"""
	runnable = ["sudo","aptitude","install","-y"]+list( [ x.split()[0] for x in getdebdeps() ] )
	Utils.pprint("GREEN","Installing DEB build dependencies")
	Utils.pprint("BLUE"," ".join(runnable))
	_check_call(runnable)

@throws_command_errors
def deploydb(ctx,virttech=None):
	if not virttech: raise Utils.WafError('use deploydb_xenserver, deploydb_vmware or deploydb_kvm rather than deploydb')
	
	ctx = _getbuildcontext()
	setupdatabases = _join(ctx.env.BINDIR,"cloud-setup-databases")
	serversetup = _join(ctx.env.SETUPDATADIR,"server-setup.xml")
	
	if not _exists(setupdatabases): # Needs install!
		Scripting.install(ctx)

	cmd = [
		ctx.env.PYTHON,
		setupdatabases,
		"cloud@%s"%ctx.env.DBHOST,
		virttech,
		"--auto=%s"%serversetup,
                "--deploy-as=%s:%s"%(ctx.env.DBUSER,ctx.env.DBPW),
		]
	
	Utils.pprint("BLUE"," ".join(cmd))
	retcode = Utils.exec_command(cmd,shell=False,stdout=None,stderr=None,log=True)
	if retcode: raise CalledProcessError(retcode,cmd)
	
def deploydb_xenserver(ctx):
	"""re-deploys the database using the MySQL connection information and the XenServer templates.sql"""
	return deploydb(ctx,"xenserver")
def deploydb_kvm(ctx):
	"""re-deploys the database using the MySQL connection information and the KVM templates.sql"""
	return deploydb(ctx,"kvm")
def deploydb_vmware(ctx):
	"""re-deploys the database using the MySQL connection information and the KVM templates.sql"""
	return deploydb(ctx,"vmware")

def run(args):
	"""runs the management server"""
	conf = _getbuildcontext()

	runverbose = []
	if Options.options.RUNVERBOSE: runverbose = ['-verbose']
	if args == "debug":
		suspend = "n"
		if Options.options.DEBUGSUSPEND: suspend = "y"
		debugargs = [
			"-Xdebug","-Xrunjdwp:transport=dt_socket,address=%s,server=y,suspend=%s"%(
				Options.options.DEBUGPORT,suspend),
			"-ea"]
		Utils.pprint("GREEN","Starting Tomcat in debug mode")
	else:
		Utils.pprint("GREEN","Starting Tomcat in foreground mode")
		debugargs = []

	options = runverbose + debugargs + [
		"-Dcatalina.base=" + conf.env.MSENVIRON,
		"-Dcatalina.home=" + conf.env.MSENVIRON,
		"-Djava.io.tmpdir="+_join(conf.env.MSENVIRON,"temp"), ]

	if not _exists(_join(conf.env.BINDIR,"cloud-setup-databases")): Scripting.install(conf)

	cp = [conf.env.MSCONF]
	cp += _glob(_join(conf.env.MSENVIRON,'bin',"*.jar"))
	cp += _glob(_join(conf.env.MSENVIRON,'lib',"*.jar"))
	cp += _glob( _join ( conf.env.PREMIUMJAVADIR , "*" ) )
	cp += [conf.env.SYSTEMCLASSPATH]
	cp += [conf.env.DEPSCLASSPATH]
	cp += [conf.env.MSCLASSPATH]

	# FIXME Make selectable at runtime
	#plugins = _glob(  _join(conf.env.PLUGINJAVADIR,"*")  )
	#if plugins: cp = plugins + cp
	#vendorconfs = _glob(  _join(conf.env.MSCONF,"vendor","*")  )
	#if vendorconfs: cp = plugins + cp

	run_java("org.apache.catalina.startup.Bootstrap",cp,options,["start"])

def debug(ctx):
	"""runs the management server in debug mode"""
	run("debug")

@throws_command_errors
def run_agent(args):
	"""runs the agent""" # FIXME: make this use the run/debug options
	conf = _getbuildcontext()
	if not _exists(_join(conf.env.LIBEXECDIR,"agent-runner")): Scripting.install(conf)
	_check_call("sudo",[_join(conf.env.LIBEXECDIR,"agent-runner")])

@throws_command_errors
#def run_console_proxy(args):
#	"""runs the console proxy""" # FIXME: make this use the run/debug options
#	conf = _getbuildcontext()
#	if not _exists(_join(conf.env.LIBEXECDIR,"console-proxy-runner")): Scripting.install(conf)
#	_check_call("sudo",[_join(conf.env.LIBEXECDIR,"console-proxy-runner")])

def simulate_agent(args):
	"""runs the agent simulator, compiling and installing files as needed
	     - Any parameter specified after the simulate_agent is appended to
	       the java command line.  To inhibit waf from interpreting the
	       command-line options that you specify to the agent, put a --
	       (double-dash) between the waf simulate_agent and the options, like this:

                    python waf simulate_agent -- -z KY -p KY
"""
	
	# to get this to work smoothly from the configure onwards, you need to
	# create an override directory in java/agent/conf, then add an agent.properties
	# there, with the correct configuration that you desire
	# that is it -- you are now ready to simulate_agent
	conf = _getbuildcontext()
	args = sys.argv[sys.argv.index("simulate_agent")+1:]
	if '--' in args: args.remove('--')
	
	cp = [conf.env.AGENTSYSCONFDIR]
	cp += _glob( _join ( conf.env.PREMIUMJAVADIR , "*" ) )
	cp += [conf.env.SYSTEMCLASSPATH]
	cp += [conf.env.DEPSCLASSPATH]
	cp += [conf.env.AGENTSIMULATORCLASSPATH]

	if not _exists(_join(conf.env.LIBEXECDIR,"agent-runner")): Scripting.install(conf)

	run_java("com.cloud.agent.AgentSimulator",cp,arguments=args)

