From b0acdbcf8be2563a6b7a287cda69dbdc5293086e Mon Sep 17 00:00:00 2001 From: "Manuel Amador (Rudd-O)" Date: Tue, 31 Aug 2010 20:39:25 -0700 Subject: [PATCH 1/3] Split out build responsibility into per-project wscript_build files. Installation of generic directories like bindir, and creation of systemvms, remain in toplevel wscript_build. Make some waf code useful and reusable in the form of tools. --- agent/wscript_build | 7 + client/wscript_build | 11 ++ console-proxy/wscript_build | 10 ++ daemonize/wscript_build | 7 + deps/wscript_build | 1 + patches/wscript_build | 29 ++++ python/wscript_build | 3 + scripts/wscript_build | 1 + server/wscript_build | 4 + tools/waf/mkisofs.py | 65 +++++++++ tools/waf/tar.py | 74 ++++++++++ ui/wscript_build | 41 ++++++ vnet/wscript_build | 21 +++ wscript | 32 +++++ wscript_build | 275 +++++------------------------------- wscript_configure | 5 +- 16 files changed, 341 insertions(+), 245 deletions(-) create mode 100644 agent/wscript_build create mode 100644 client/wscript_build create mode 100644 console-proxy/wscript_build create mode 100644 daemonize/wscript_build create mode 100644 deps/wscript_build create mode 100644 patches/wscript_build create mode 100644 python/wscript_build create mode 100644 scripts/wscript_build create mode 100644 server/wscript_build create mode 100644 tools/waf/mkisofs.py create mode 100644 tools/waf/tar.py create mode 100644 ui/wscript_build create mode 100644 vnet/wscript_build diff --git a/agent/wscript_build b/agent/wscript_build new file mode 100644 index 00000000000..583f4ac8963 --- /dev/null +++ b/agent/wscript_build @@ -0,0 +1,7 @@ +import Options + +bld.install_files("${AGENTLIBDIR}", + bld.path.ant_glob("storagepatch/**",src=True,bld=False,dir=False,flat=True), + cwd=bld.path,relative_trick=True) +if not Options.options.PRESERVECONFIG: + bld.install_files_filtered("${AGENTSYSCONFDIR}","conf/*") diff --git a/client/wscript_build b/client/wscript_build new file mode 100644 index 00000000000..3c153257032 --- /dev/null +++ b/client/wscript_build @@ -0,0 +1,11 @@ +import Options + +start_path = bld.path.find_dir("WEB-INF") +bld.install_files('${MSENVIRON}/webapps/client/WEB-INF', + start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), + cwd=start_path,relative_trick=True) + +if not Options.options.PRESERVECONFIG: + bld.install_files_filtered("${MSCONF}","tomcatconf/*") + bld.install_files("${MSCONF}",'tomcatconf/db.properties',chmod=0640) + bld.setownership("${MSCONF}/db.properties","root",bld.env.MSUSER) diff --git a/console-proxy/wscript_build b/console-proxy/wscript_build new file mode 100644 index 00000000000..d5221157768 --- /dev/null +++ b/console-proxy/wscript_build @@ -0,0 +1,10 @@ +import Options + +# binary unsubstitutable files: +bld.install_files("${CPLIBDIR}",bld.path.ant_glob("images/**",src=True,bld=False,dir=False,flat=True),cwd=bld.path,relative_trick=True) + +# text substitutable files (substitute with tokens from the environment bld.env): +bld.substitute('css/** js/** ui/** scripts/**',install_to="${CPLIBDIR}") + +# config files (do not replace them if preserve config option is true) +if not Options.options.PRESERVECONFIG: bld.install_files_filtered("${CPSYSCONFDIR}","conf.dom0/*") diff --git a/daemonize/wscript_build b/daemonize/wscript_build new file mode 100644 index 00000000000..ce5741a741a --- /dev/null +++ b/daemonize/wscript_build @@ -0,0 +1,7 @@ +if bld.env.DISTRO not in ['Windows','Mac']: + # build / install declarations of the daemonization utility - except for Windows + bld( + name='daemonize', + features='cc cprogram', + source='daemonize.c', + target='cloud-daemonize') \ No newline at end of file diff --git a/deps/wscript_build b/deps/wscript_build new file mode 100644 index 00000000000..11697814dd0 --- /dev/null +++ b/deps/wscript_build @@ -0,0 +1 @@ +bld.install_files('${JAVADIR}','*.jar') diff --git a/patches/wscript_build b/patches/wscript_build new file mode 100644 index 00000000000..4351d4e605d --- /dev/null +++ b/patches/wscript_build @@ -0,0 +1,29 @@ +import os, Utils, glob, re + +bld.substitute("*/**",name="patchsubst") + +for virttech in Utils.to_list(bld.path.ant_glob("*",dir=True)): + if virttech in ["shared","wscript_build"]: continue + patchfiles = bld.path.ant_glob('%s/** shared/**'%virttech,src=True,bld=True,dir=False,flat=True) + tgen = bld( + features = 'tar',#Utils.tar_up, + source = patchfiles, + target = '%s-patch.tgz'%virttech, + name = '%s-patch_tgz'%virttech, + root = "patches/%s"%virttech, + rename = lambda x: re.sub(".subst$","",x), + after = 'patchsubst', + ) + bld.process_after(tgen) + if virttech != "xenserver": + # xenserver uses the patch.tgz file later to make an ISO, so we do not need to install it + bld.install_as("${AGENTLIBDIR}/scripts/vm/hypervisor/%s/patch.tgz"%virttech, "%s-patch.tgz"%virttech) + +tgen = bld( + rule = 'cp ${SRC} ${TGT}', + source = 'xenserver-patch.tgz', + target = 'patch.tgz', + after = 'xenserver-patch_tgz', + name = 'patch_tgz' +) +bld.process_after(tgen) diff --git a/python/wscript_build b/python/wscript_build new file mode 100644 index 00000000000..4b78e04b404 --- /dev/null +++ b/python/wscript_build @@ -0,0 +1,3 @@ +if bld.env.DISTRO not in ['Windows','Mac']: + obj = bld(features = 'py',name='pythonmodules') + obj.find_sources_in_dirs('lib', exts=['.py']) diff --git a/scripts/wscript_build b/scripts/wscript_build new file mode 100644 index 00000000000..6730263e22f --- /dev/null +++ b/scripts/wscript_build @@ -0,0 +1 @@ +bld.substitute('**',"${AGENTLIBDIR}/scripts",chmod=0755) diff --git a/server/wscript_build b/server/wscript_build new file mode 100644 index 00000000000..f6660680f77 --- /dev/null +++ b/server/wscript_build @@ -0,0 +1,4 @@ +import Options + +if not Options.options.PRESERVECONFIG: + bld.install_files_filtered("${SERVERSYSCONFDIR}","conf/*") diff --git a/tools/waf/mkisofs.py b/tools/waf/mkisofs.py new file mode 100644 index 00000000000..eb611577208 --- /dev/null +++ b/tools/waf/mkisofs.py @@ -0,0 +1,65 @@ +import Utils +from TaskGen import feature, before +import Task +import os + +# fixme: this seems to hang waf with 100% CPU + +def detect(conf): + conf.find_program("mkisofs",mandatory=True,var='MKISOFS') + +def iso_up(task): + tgt = task.outputs[0].bldpath(task.env) + if os.path.exists(tgt): os.unlink(tgt) + inps = [] + for inp in task.inputs: + if inp.id&3==Node.BUILD: + src = inp.bldpath(task.env) + srcname = src + srcname = "/".join(srcname.split("/")[1:]) # chop off default/ + else: + src = inp.srcpath(task.env) + srcname = src + srcname = "/".join(srcname.split("/")[1:]) # chop off ../ + inps.append(src) + ret = Utils.exec_command( + [ + task.generator.env.MKISOFS, + "-quiet", + "-r", + "-o",tgt, + ] + inps, shell=False) + if ret != 0: return ret + if task.chmod: os.chmod(tgt,task.chmod) + +def apply_iso(self): + Utils.def_attrs(self,fun=iso_up) + self.default_install_path=0 + lst=self.to_list(self.source) + self.meths.remove('apply_core') + self.dict=getattr(self,'dict',{}) + out = self.path.find_or_declare(self.target) + ins = [] + for x in Utils.to_list(self.source): + node = self.path.find_resource(x) + if not node:raise Utils.WafError('cannot find input file %s for processing'%x) + ins.append(node) + if self.dict and not self.env['DICT_HASH']: + self.env=self.env.copy() + keys=list(self.dict.keys()) + keys.sort() + lst=[self.dict[x]for x in keys] + self.env['DICT_HASH']=str(Utils.h_list(lst)) + tsk=self.create_task('iso',ins,out) + tsk.fun=self.fun + tsk.dict=self.dict + tsk.dep_vars=['DICT_HASH'] + tsk.install_path=self.install_path + tsk.chmod=self.chmod + if not tsk.env: + tsk.debug() + raise Utils.WafError('task without an environment') + +Task.task_type_from_func('iso',func=iso_up) +feature('iso')(apply_iso) +before('apply_core')(apply_iso) \ No newline at end of file diff --git a/tools/waf/tar.py b/tools/waf/tar.py new file mode 100644 index 00000000000..c0293337b90 --- /dev/null +++ b/tools/waf/tar.py @@ -0,0 +1,74 @@ +import Utils +import tarfile +from TaskGen import feature, before +import Task +import os + +# this is a clever little thing +# given a list of nodes, build or source +# construct a tar file containing them +# rooted in the parameter root =, specified in the task generator +# and renaming the names of the files according to a rename(x) function passed to the task generator as well +# if a build node's result of rename() has the same name as a source node, the build node will take precedence +# for as long as the build node appears later than the source node (this is an implementation detail of waf we are relying on) +def tar_up(task): + tgt = task.outputs[0].bldpath(task.env) + if os.path.exists(tgt): os.unlink(tgt) + if tgt.lower().endswith(".bz2"): z = tarfile.open(tgt,"w:bz2") + elif tgt.lower().endswith(".gz"): z = tarfile.open(tgt,"w:gz") + elif tgt.lower().endswith(".tgz"): z = tarfile.open(tgt,"w:gz") + else: z = tarfile.open(tgt,"w") + fileset = {} + for inp in task.inputs: + src = inp.srcpath(task.env) + if src.startswith(".."): + srcname = Utils.relpath(src,os.path.join("..",".")) # file in source dir + else: + srcname = Utils.relpath(src,os.path.join(task.env.variant(),".")) # file in artifacts dir + if task.generator.rename: srcname = task.generator.rename(srcname) + for dummy in task.generator.root.split("/"): + splittedname = srcname.split("/") + srcname = "/".join(splittedname[1:]) + fileset[srcname] = src + for srcname,src in fileset.items(): + ti = tarfile.TarInfo(srcname) + ti.mode = 0755 + ti.size = os.path.getsize(src) + f = file(src) + z.addfile(ti,fileobj=f) + f.close() + z.close() + if task.chmod: os.chmod(tgt,task.chmod) + return 0 + +def apply_tar(self): + Utils.def_attrs(self,fun=tar_up) + self.default_install_path=0 + lst=self.to_list(self.source) + self.meths.remove('apply_core') + self.dict=getattr(self,'dict',{}) + out = self.path.find_or_declare(self.target) + ins = [] + for x in Utils.to_list(self.source): + node = self.path.find_resource(x) + if not node:raise Utils.WafError('cannot find input file %s for processing'%x) + ins.append(node) + if self.dict and not self.env['DICT_HASH']: + self.env=self.env.copy() + keys=list(self.dict.keys()) + keys.sort() + lst=[self.dict[x]for x in keys] + self.env['DICT_HASH']=str(Utils.h_list(lst)) + tsk=self.create_task('tar',ins,out) + tsk.fun=self.fun + tsk.dict=self.dict + tsk.dep_vars=['DICT_HASH'] + tsk.install_path=self.install_path + tsk.chmod=self.chmod + if not tsk.env: + tsk.debug() + raise Utils.WafError('task without an environment') + +Task.task_type_from_func('tar',func=tar_up) +feature('tar')(apply_tar) +before('apply_core')(apply_tar) \ No newline at end of file diff --git a/ui/wscript_build b/ui/wscript_build new file mode 100644 index 00000000000..ab3805ecef5 --- /dev/null +++ b/ui/wscript_build @@ -0,0 +1,41 @@ +import Utils, os + +# binary unsubstitutable files: +bld.install_files("${MSENVIRON}/webapps/client",bld.path.ant_glob("*.ico **/*png **/*jpg **/*gif",src=True,bld=False,dir=False,flat=True),cwd=bld.path,relative_trick=True) + +# text substitutable files (substitute with tokens from the environment bld.env): +bld.substitute('*html **/*html **/*js **/*css **/*properties **/*jsp *jsp',install_to="${MSENVIRON}/webapps/client") + +# -> minification of UI files +def minifyjs(task): + tgt = task.outputs[0].bldpath(task.env) + inputfiles = [] + outputfile = ['--js_output_file',tgt] + for inp in task.inputs: + src = inp.srcpath(task.env) + inputfiles.append(src) + newinputfiles = [] + for inputfile in inputfiles: + if inputfile not in newinputfiles: + newinputfiles.append('--js') + newinputfiles.append(inputfile) + compilerjar = os.path.join(bld.srcnode.abspath(),'tools','gcc','compiler.jar') + return Utils.exec_command(["java",'-jar',compilerjar] + newinputfiles + outputfile,log=True) + +javascripts = [ + ['scripts/jquery-1.4.2.min.js','scripts/date.js'], + Utils.to_list(bld.path.ant_glob('scripts/jquery*js')), + ['scripts/cloud.core.js','scripts/cloud.core.callbacks.js'], + Utils.to_list(bld.path.ant_glob('scripts/cloud*js')), +] +sourcefiles = [] +for lst in javascripts: + for x in lst: + if x not in sourcefiles: sourcefiles.append(x) +tgen = bld( + rule = minifyjs, + source = sourcefiles, + target = 'scripts/cloud.min.js', + name = 'minifyjs', +) +bld.install_files("${MSENVIRON}/webapps/client/scripts", "scripts/cloud.min.js") diff --git a/vnet/wscript_build b/vnet/wscript_build new file mode 100644 index 00000000000..270368b32c3 --- /dev/null +++ b/vnet/wscript_build @@ -0,0 +1,21 @@ +import Utils + +if bld.env.DISTRO not in ['Windows','Mac']: + # build / install declarations of vnet + files = """vnetd/connection.c vnetd/select.c vnetd/timer.c vnetd/spinlock.c vnetd/skbuff.c + vnetd/vnetd.c vnet-module/skb_util.c vnet-module/sxpr_util.c vnet-module/timer_util.c + vnet-module/etherip.c vnet-module/vnet.c vnet-module/vnet_eval.c vnet-module/vnet_forward.c + vnet-module/vif.c vnet-module/tunnel.c vnet-module/sa.c vnet-module/varp.c + libxutil/allocate.c libxutil/enum.c libxutil/file_stream.c libxutil/hash_table.c + libxutil/iostream.c libxutil/lexis.c libxutil/socket_stream.c libxutil/string_stream.c + libxutil/sxpr.c libxutil/sxpr_parser.c libxutil/sys_net.c libxutil/sys_string.c libxutil/util.c""" + files = [ "src/%s"%s for s in Utils.to_list(files) ] + bld( + name='vnetd', + features='cc cprogram', + source= files, + includes="src/libxutil src/vnet-module src/vnetd", + lib='dl pthread'.split(), + target='%s-vnetd'%bld.env.PACKAGE, + install_path="${SBINDIR}" + ) diff --git a/wscript b/wscript index 1c212ab0438..9286ded759a 100644 --- a/wscript +++ b/wscript @@ -342,6 +342,24 @@ def _install_files_filtered(self,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 + tgen = self(features='subst', source=src, target=tgt, **tgenkwargs) + 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, **kwargs) +Build.BuildContext.substitute = _substitute + def _setownership(ctx,path,owner,group,mode=None): def f(bld,path,owner,group,mode): dochown = not Options.options.NOCHOWN \ @@ -382,6 +400,8 @@ Build.BuildContext.setownership = _setownership def set_options(opt): """Register command line options""" opt.tool_options('gnu_dirs') + opt.tool_options('tar',tooldir='tools/waf') + opt.tool_options('mkisofs',tooldir='tools/waf') if platform.system() not in ['Windows',"Darwin"]: opt.tool_options('compiler_cc') opt.tool_options('python') @@ -487,6 +507,18 @@ def showconfig(conf): 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""" diff --git a/wscript_build b/wscript_build index 34b46d24ece..8599da6cf4e 100644 --- a/wscript_build +++ b/wscript_build @@ -8,7 +8,7 @@ import shutil,os import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure 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 +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 try: set([1,2,3]) except Exception: from Sets import set @@ -42,17 +42,7 @@ sccsinfo = _join(sourcedir,"sccs-info") if _exists(sccsinfo): bld.install_files("${DOCDIR}","sccs-info") tgen = bld(features='subst', name='configure-info', source="configure-info.in", target="configure-info") -def gen_configure_info(): - lines = [] - for key,val in sorted(bld.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) -tgen.dict = {"CONFIGUREVARS":gen_configure_info()} +tgen.dict = {"CONFIGUREVARS":bld.getconfig()} bld.install_files("${DOCDIR}","configure-info") # ==================== Java compilation =========================== @@ -117,69 +107,22 @@ bld.process_after(tgen) # =================== C / Python compilation ========================= -if bld.env.DISTRO not in ['Windows','Mac']: - # build / install declarations of the daemonization utility - except for Windows - bld( - name='daemonize', - features='cc cprogram', - source='daemonize/daemonize.c', - target='daemonize/cloud-daemonize') - - # build / install declarations of vnet - files = """vnetd/connection.c vnetd/select.c vnetd/timer.c vnetd/spinlock.c vnetd/skbuff.c - vnetd/vnetd.c vnet-module/skb_util.c vnet-module/sxpr_util.c vnet-module/timer_util.c - vnet-module/etherip.c vnet-module/vnet.c vnet-module/vnet_eval.c vnet-module/vnet_forward.c - vnet-module/vif.c vnet-module/tunnel.c vnet-module/sa.c vnet-module/varp.c - libxutil/allocate.c libxutil/enum.c libxutil/file_stream.c libxutil/hash_table.c - libxutil/iostream.c libxutil/lexis.c libxutil/socket_stream.c libxutil/string_stream.c - libxutil/sxpr.c libxutil/sxpr_parser.c libxutil/sys_net.c libxutil/sys_string.c libxutil/util.c""" - files = [ "vnet/src/%s"%s for s in Utils.to_list(files) ] - bld( - name='vnetd', - features='cc cprogram', - source= files, - includes="vnet/src/libxutil vnet/src/vnet-module vnet/src/vnetd", - lib='dl pthread'.split(), - target='vnet/%s-vnetd'%bld.env.PACKAGE, - install_path="${SBINDIR}" - ) - - obj = bld(features = 'py',name='pythonmodules') - obj.find_sources_in_dirs('python/lib', exts=['.py']) +bld.recurse(["vnet","daemonize","python"],'build') # ===================== End C / Python compilation ========================== # ================ Third-party / dependency installation =============== -bld.install_files('${JAVADIR}','deps/*.jar') -if buildpremium: bld.install_files('${PREMIUMJAVADIR}','cloudstack-proprietary/thirdparty/*.jar') +bld.recurse(["deps"],'build') +if buildpremium: bld.recurse(['cloudstack-proprietary/thirdparty'],'build') # =================== End 3rdparty/dep install ======================== # =================== Build install declaratoin of console proxy project ======== -# -> binary unsubstitutable files -start_path = bld.path.find_dir("console-proxy") -bld.install_files("${CPLIBDIR}", - start_path.ant_glob("images/**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) - -# -> source files with tokens -patterns = 'console-proxy/css/** console-proxy/js/** console-proxy/ui/** console-proxy/scripts/**' -src_files = Utils.to_list(filelist(patterns,flat=True)) -subst_files = [ x+".subst" for x in src_files ] -inst_files = [ Utils.relpath(x,"console-proxy") for x in src_files ] -for src,tgt,inst in zip(src_files,subst_files,inst_files): - tgen = bld(features='subst', source=src, target=tgt) - tgen.dict = bld.env.get_merged_dict() - bld.path.find_or_declare(tgt) - bld.install_as("${CPLIBDIR}/%s"%inst, tgt) - -# -> configuration -if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${CPSYSCONFDIR}",filelist("console-proxy/conf.dom0/*")) +bld.recurse(["console-proxy"],'build') # ================== End console proxy =================== @@ -187,74 +130,7 @@ if not Options.options.PRESERVECONFIG: # ================ Creation of patch.tgz's ============================ # done here because the patches require substituted files -patterns = "patches/**" -src_files = Utils.to_list(filelist(patterns,flat=True)) -subst_files = [ x+".subst" for x in src_files ] -inst_files = src_files -for src,tgt,inst in zip(src_files,subst_files,inst_files): - tgen = bld(features='subst', name='patchsubst', source=src, target=tgt) - tgen.dict = bld.env.get_merged_dict() - bld.path.find_or_declare(tgt) - -# this is a clever little thing -# given a list of nodes, build or source -# construct a tar file containing them -# rooted in the parameter root =, specified in the task generator -# and renaming the names of the files according to a rename(x) function passed to the task generator as well -# if a build node's result of rename() has the same name as a source node, the build node will take precedence -# for as long as the build node appears later than the source node (this is an implementation detail of waf we are relying on) -def tar_up(task): - tgt = task.outputs[0].bldpath(task.env) - if _exists(tgt): _unlink(tgt) - z = tarfile.open(tgt,"w:gz") - fileset = {} - for inp in task.inputs: - src = inp.srcpath(task.env) - if src.startswith(".."): - srcname = Utils.relpath(src,_join("..",".")) # file in source dir - else: - srcname = Utils.relpath(src,_join(task.env.variant(),".")) # file in artifacts dir - if task.generator.rename: srcname = task.generator.rename(srcname) - for dummy in task.generator.root.split("/"): - splittedname = srcname.split("/") - srcname = "/".join(splittedname[1:]) - fileset[srcname] = src - for srcname,src in fileset.items(): - ti = tarfile.TarInfo(srcname) - ti.mode = 0755 - ti.size = os.path.getsize(src) - f = file(src) - z.addfile(ti,fileobj=f) - f.close() - z.close() - return 0 - -for virttech in [ _basename(x) for x in _glob(_join("patches","*")) ]: - if virttech == "shared": - continue - patchfiles = filelist('patches/%s/** patches/shared/**'%virttech,src=True,bld=True,dir=False,flat=True) - tgen = bld( - rule = tar_up, - source = patchfiles, - target = '%s-patch.tgz'%virttech, - name = '%s-patch_tgz'%virttech, - root = "patches/%s"%virttech, - rename = lambda x: re.sub(".subst$","",x), - after = 'patchsubst', - ) - bld.process_after(tgen) - if virttech != "xenserver": - # xenserver uses the patch.tgz file later to make an ISO, so we do not need to install it - bld.install_as("${AGENTLIBDIR}/scripts/vm/hypervisor/%s/patch.tgz"%virttech, "%s-patch.tgz"%virttech) - -tgen = bld( - rule = 'cp ${SRC} ${TGT}', - source = 'xenserver-patch.tgz', - target = 'patch.tgz', - after = 'xenserver-patch_tgz', - name = 'patch_tgz' -) -bld.process_after(tgen) +bld.recurse(["patches"],'build') # ================== End creation of patch.tgz's ==================== @@ -386,7 +262,7 @@ if buildpremium: def iso_up(task): tgt = task.outputs[0].bldpath(task.env) - if _exists(tgt): _unlink(tgt) + if os.path.exists(tgt): os.unlink(tgt) inps = [] for inp in task.inputs: if inp.id&3==Node.BUILD: @@ -397,30 +273,32 @@ def iso_up(task): src = inp.srcpath(task.env) srcname = src srcname = "/".join(srcname.split("/")[1:]) # chop off ../ - # post-process the paths inps.append(src) - return Utils.exec_command( + ret = Utils.exec_command( [ task.generator.env.MKISOFS, "-quiet", "-r", "-o",tgt, - ] + inps) + ] + inps, shell=False) + if ret != 0: return ret -tgen = bld( - rule = iso_up, - source = "patch.tgz target/oss/systemvm.zip", - target = 'target/oss/systemvm.iso', - name = 'systemvm_iso', - after = 'systemvm_zip patch_tgz', -) -bld.process_after(tgen) -bld.install_as("${AGENTLIBDIR}/vms/systemvm.iso", "target/oss/systemvm.iso") +if bld.env.DISTRO not in ["Windows","Mac"]: + # systemvm.zip cannot be built on Windows or Mac because system deps do not exist there + tgen = bld( + rule = iso_up, + source = "patches/patch.tgz target/oss/systemvm.zip", + target = 'target/oss/systemvm.iso', + name = 'systemvm_iso', + after = 'systemvm_zip patch_tgz', + ) + bld.process_after(tgen) + bld.install_as("${AGENTLIBDIR}/vms/systemvm.iso", "target/oss/systemvm.iso") if buildpremium: tgen = bld( - rule = iso_up, - source = "patch.tgz target/premium/systemvm.zip", + rule = iso_up, + source = "patches/patch.tgz target/premium/systemvm.zip", target = 'target/premium/systemvm.iso', name = 'systemvm-premium_iso', after = 'systemvm-premium_zip patch_tgz', @@ -481,15 +359,8 @@ else: # =================== Subst / installation of agent scripts project ======== -src_files = Utils.to_list(filelist("scripts/** cloudstack-proprietary/scripts/**",flat=True)) -subst_files = [ x+".subst" for x in src_files ] -inst_files = src_files -for src,tgt,inst in zip(src_files,subst_files,inst_files): - tgen = bld(features='subst', name='scriptssubst', source=src, target=tgt) - tgen.dict = bld.env.get_merged_dict() - bld.path.find_or_declare(tgt) - if inst.startswith("cloudstack-proprietary"): inst = inst[len("cloudstack-proprietary")+1:] - bld.install_as("${AGENTLIBDIR}/%s"%inst, tgt, chmod=0755) +bld.recurse(["scripts"],'build') +if buildpremium: bld.recurse(["cloudstack-proprietary/scripts"],'build') # ================== End agent scripts =================== @@ -506,94 +377,17 @@ bld.install_files_filtered("${SBINDIR}","*/sbindir/* cloudstack-proprietary/*/sb # ================== Installation of scripts / bindirs / configuration files =========================== # build / install declarations of test project -if buildpremium: - proj = 'test' - start_path = bld.path.find_dir("cloudstack-proprietary/test/scripts") - bld.install_files('${LIBDIR}/${PACKAGE}/test', - start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) - start_path = bld.path.find_dir("cloudstack-proprietary/test/metadata") - bld.install_files('${SHAREDSTATEDIR}/${PACKAGE}/test', - start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) - if not Options.options.PRESERVECONFIG: - bld.install_files('${SYSCONFDIR}/%s/%s'%(bld.env.PACKAGE,proj),'cloudstack-proprietary/test/conf/*') +if buildpremium: bld.recurse(["cloudstack-proprietary/test"],'build') # build / install declarations of server project <- this is actually now in client project -start_path = bld.path.find_dir("client/WEB-INF") -bld.install_files('${MSENVIRON}/webapps/client/WEB-INF', - start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) -if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${SERVERSYSCONFDIR}","server/conf/*") +bld.recurse(["client","server"],'build') +if buildpremium: bld.recurse(["cloudstack-proprietary/premium"],'build') # build / install declarations of agent project -proj = 'agent' -start_path = bld.path.find_dir(proj) -bld.install_files("${AGENTLIBDIR}", - start_path.ant_glob("storagepatch/**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) -if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${AGENTSYSCONFDIR}","%s/conf/*"%proj) +bld.recurse(["agent"],'build') # build / install declarations of client UI project - -# -> binary unsubstitutable files -start_path = bld.path.find_dir("ui") -bld.install_files("${MSENVIRON}/webapps/client", - start_path.ant_glob("*.ico **/*png **/*jpg **/*gif",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) - -# -> source files with tokens -patterns = 'ui/*html ui/**/*html ui/**/*js ui/**/*css ui/**/*properties ui/**/*jsp' -src_files = Utils.to_list(filelist(patterns,flat=True)) -subst_files = [ x+".subst" for x in src_files ] -inst_files = [ Utils.relpath(x,"ui") for x in src_files ] -for src,tgt,inst in zip(src_files,subst_files,inst_files): - tgen = bld(features='subst', source=src, target=tgt) - tgen.dict = bld.env.get_merged_dict() - bld.path.find_or_declare(tgt) - bld.install_as("${MSENVIRON}/webapps/client/%s"%inst, tgt) - -# -> minification of UI files -def minifyjs(task): - tgt = task.outputs[0].bldpath(task.env) - inputfiles = [] - outputfile = ['--js_output_file',tgt] - for inp in task.inputs: - src = inp.srcpath(task.env) - inputfiles.append(src) - newinputfiles = [] - for inputfile in inputfiles: - if inputfile not in newinputfiles: - newinputfiles.append('--js') - newinputfiles.append(inputfile) - compilerjar = _join(sourcedir,'tools','gcc','compiler.jar') - return Utils.exec_command(["java",'-jar',compilerjar] + newinputfiles + outputfile,log=True) - -javascripts = [ - ['ui/scripts/jquery-1.4.2.min.js','ui/scripts/date.js'], - Utils.to_list(filelist('ui/scripts/jquery*js')), - ['ui/scripts/cloud.core.js','ui/scripts/cloud.core.callbacks.js'], - Utils.to_list(filelist('ui/scripts/cloud*js')), -] -sourcefiles = [] -for lst in javascripts: - for x in lst: - if x not in sourcefiles: sourcefiles.append(x) -tgen = bld( - rule = minifyjs, - source = sourcefiles, - target = 'ui/scripts/cloud.min.js', - name = 'minifyjs', -) -bld.install_files("${MSENVIRON}/webapps/client/scripts", "ui/scripts/cloud.min.js") - -# substitute and install generic tomcat config -if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${MSCONF}","*/tomcatconf/* cloudstack-proprietary/*/tomcatconf/*") - bld.install_files("${MSCONF}",'client/tomcatconf/db.properties',chmod=0640) - bld.setownership("${MSCONF}/db.properties","root",bld.env.MSUSER) +bld.recurse(["ui"],'build') # apply distro-specific config on top of the 'all' generic cloud-management config globspec = _join("*","distro",bld.env.DISTRO.lower(),"*") # matches premium/distro/centos/SYSCONFDIR @@ -610,12 +404,7 @@ for dsdir in distrospecificdirs: bld.install_files_filtered(dsdirwithvar, files, cwd=start_path, relative_trick=True,chmod=mode) # build / install declarations of usage -if buildpremium: - if not Options.options.PRESERVECONFIG: - #print filelist("usage/conf/* cloudstack-proprietary/usage/conf/*") - #assert False - bld.install_files_filtered("${USAGESYSCONFDIR}","usage/conf/* cloudstack-proprietary/usage/conf/*") - bld.symlink_as("${USAGESYSCONFDIR}/db.properties",Utils.subst_vars("${MSCONF}/db.properties",bld.env)) +if buildpremium: bld.recurse(["cloudstack-proprietary/usage"],'build') # install db data files bld.install_files_filtered("${SETUPDATADIR}",filelist("*/db/* cloudstack-proprietary/*/db/*",excl=Node.exclude_regs + "\ncloud-gate\ncloud-bridge")) diff --git a/wscript_configure b/wscript_configure index 7294b61f59d..829ddc72c15 100644 --- a/wscript_configure +++ b/wscript_configure @@ -89,11 +89,12 @@ hard_deps = [ conf.check_tool('misc') -conf.check_tool('java') conf.check_tool("gnu_dirs") +conf.check_tool('tar') +conf.check_tool('mkisofs') +conf.check_tool('java') conf.check_tool("python") conf.check_python_version((2,4,0)) -conf.find_program("mkisofs",mandatory=True,var='MKISOFS') conf.check_message_1('Detecting distribution') if platform.system() == 'Windows': conf.env.DISTRO = "Windows" From 9535dc8f4da88991c0c8c1b23e49fda224c6ec0f Mon Sep 17 00:00:00 2001 From: abhishek Date: Wed, 1 Sep 2010 10:38:22 -0700 Subject: [PATCH 2/3] bug 6023: Implemented the search by group status 6023: resolved fixed --- .../xen/resource/CitrixResourceBase.java | 2 +- core/src/com/cloud/server/Criteria.java | 3 ++- core/src/com/cloud/vm/dao/UserVmDaoImpl.java | 2 ++ .../com/cloud/api/commands/ListVMsCmd.java | 10 ++++++++ .../cloud/server/ManagementServerImpl.java | 23 ++++++++++++++++--- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 069e31b26c9..f04aa4dd702 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1,5 +1,5 @@ /** -: * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * diff --git a/core/src/com/cloud/server/Criteria.java b/core/src/com/cloud/server/Criteria.java index f2d7090341c..6d41b967be9 100644 --- a/core/src/com/cloud/server/Criteria.java +++ b/core/src/com/cloud/server/Criteria.java @@ -76,7 +76,8 @@ public class Criteria { public static final String TARGET_IQN = "targetiqn"; public static final String SCOPE = "scope"; public static final String NETWORKGROUP = "networkGroup"; - + public static final String GROUP = "group"; + public static final String EMPTY_GROUP = "emptyGroup"; public Criteria(String orderBy, Boolean ascending, Long offset, Long limit) { this.offset = offset; diff --git a/core/src/com/cloud/vm/dao/UserVmDaoImpl.java b/core/src/com/cloud/vm/dao/UserVmDaoImpl.java index 6ab439486af..4e909b7b9f3 100755 --- a/core/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/core/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -116,6 +116,8 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use DestroySearch.and("updateTime", DestroySearch.entity().getUpdateTime(), SearchCriteria.Op.LT); DestroySearch.done(); + + _updateTimeAttr = _allAttributes.get("updateTime"); assert _updateTimeAttr != null : "Couldn't get this updateTime attribute"; } diff --git a/server/src/com/cloud/api/commands/ListVMsCmd.java b/server/src/com/cloud/api/commands/ListVMsCmd.java index 0a61217a95c..5989d982630 100644 --- a/server/src/com/cloud/api/commands/ListVMsCmd.java +++ b/server/src/com/cloud/api/commands/ListVMsCmd.java @@ -53,6 +53,7 @@ public class ListVMsCmd extends BaseCmd { s_properties.add(new Pair(BaseCmd.Properties.STATE, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.POD_ID, Boolean.FALSE)); + s_properties.add(new Pair(BaseCmd.Properties.GROUP, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.HOST_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.KEYWORD, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT, Boolean.FALSE)); @@ -82,6 +83,7 @@ public class ListVMsCmd extends BaseCmd { Long zoneId = (Long)params.get(BaseCmd.Properties.ZONE_ID.getName()); Long podId = (Long)params.get(BaseCmd.Properties.POD_ID.getName()); Long hostId = (Long)params.get(BaseCmd.Properties.HOST_ID.getName()); + String group = (String)params.get(BaseCmd.Properties.GROUP.getName()); String keyword = (String)params.get(BaseCmd.Properties.KEYWORD.getName()); Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName()); Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName()); @@ -140,6 +142,14 @@ public class ListVMsCmd extends BaseCmd { if(zoneId != null) c.addCriteria(Criteria.DATACENTERID, zoneId); + if(group != null) + { + if(group.equals("")) + c.addCriteria(Criteria.EMPTY_GROUP, group); + else + c.addCriteria(Criteria.GROUP, group); + } + // ignore these search requests if it's not an admin if (isAdmin == true) { c.addCriteria(Criteria.DOMAINID, domainId); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 3c65b3033e3..a1ce58b1599 100644 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -4989,7 +4989,6 @@ public class ManagementServerImpl implements ManagementServer { public List searchForUserVMs(Criteria c) { Filter searchFilter = new Filter(UserVmVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); SearchBuilder sb = _userVmDao.createSearchBuilder(); - // some criteria matter for generating the join condition Object[] accountIds = (Object[]) c.getCriteria(Criteria.ACCOUNTID); Object domainId = c.getCriteria(Criteria.DOMAINID); @@ -5006,7 +5005,8 @@ public class ManagementServerImpl implements ManagementServer { Object keyword = c.getCriteria(Criteria.KEYWORD); Object isAdmin = c.getCriteria(Criteria.ISADMIN); Object ipAddress = c.getCriteria(Criteria.IPADDRESS); - + Object vmGroup = c.getCriteria(Criteria.GROUP); + Object emptyGroup = c.getCriteria(Criteria.EMPTY_GROUP); sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("accountIdEQ", sb.entity().getAccountId(), SearchCriteria.Op.EQ); @@ -5020,7 +5020,8 @@ public class ManagementServerImpl implements ManagementServer { sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ); sb.and("hostIdIN", sb.entity().getHostId(), SearchCriteria.Op.IN); sb.and("guestIP", sb.entity().getGuestIpAddress(), SearchCriteria.Op.EQ); - + sb.and("groupEQ", sb.entity().getGroup(),SearchCriteria.Op.EQ); + if ((accountIds == null) && (domainId != null)) { // if accountId isn't specified, we can do a domain match for the admin case SearchBuilder domainSearch = _domainDao.createSearchBuilder(); @@ -5109,7 +5110,23 @@ public class ManagementServerImpl implements ManagementServer { if (ipAddress != null) { sc.setParameters("guestIP", ipAddress); } + + if(vmGroup!=null) + sc.setParameters("groupEQ", vmGroup); + + if (emptyGroup!= null) + { + SearchBuilder emptyGroupSearch = _userVmDao.createSearchBuilder(); + emptyGroupSearch.and("group", emptyGroupSearch.entity().getGroup(), SearchCriteria.Op.EQ); + emptyGroupSearch.or("null", emptyGroupSearch.entity().getGroup(), SearchCriteria.Op.NULL); + SearchCriteria sc1 = _userVmDao.createSearchCriteria(); + sc1 = emptyGroupSearch.create(); + sc1.setParameters("group", ""); + + sc.addAnd("group", SearchCriteria.Op.SC, sc1); + } + return _userVmDao.search(sc, searchFilter); } From c761746ff25f7d85431b12ddb1d886972f324f6e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2010 11:08:04 -0700 Subject: [PATCH 3/3] New UI VM wizard-add name field, group field --- ui/new/index.jsp | 2 +- ui/new/jsp/tab_instance.jsp | 25 ++++++++++++++-- ui/new/scripts/cloud.core.instance.js | 41 ++++++++++++++------------- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/ui/new/index.jsp b/ui/new/index.jsp index 35b3e71c526..04f8230d2ae 100644 --- a/ui/new/index.jsp +++ b/ui/new/index.jsp @@ -608,7 +608,7 @@

- IP Address: + IP Address:

-
+
@@ -537,7 +537,28 @@ Network:
+
+
+
+
+
+
+ Name (optional): +
+ + +
+
+
+
+
+
+ Group (optional):
+ + +
+
@@ -570,7 +591,7 @@ diff --git a/ui/new/scripts/cloud.core.instance.js b/ui/new/scripts/cloud.core.instance.js index e5d41b4e533..94cc5e51c3f 100755 --- a/ui/new/scripts/cloud.core.instance.js +++ b/ui/new/scripts/cloud.core.instance.js @@ -518,13 +518,13 @@ function clickInstanceGroupHeader($arrowIcon) { //***** data disk offering: "no, thanks", "custom", existing disk offerings in database (begin) **************************************************** //"no, thanks" radio button (default radio button in data disk offering) var $t = $noDiskOfferingTemplate.clone(); - $t.find("input:radio").attr("name","data_disk_offering_radio").val("no"); + $t.find("input:radio").attr("name","data_disk_offering_radio"); $t.find("#name").text("no, thanks"); $dataDiskOfferingContainer.append($t.show()); //"custom" radio button var $t = $customDiskOfferingTemplate.clone(); - $t.find("input:radio").attr("name","data_disk_offering_radio").val("custom").removeAttr("checked"); + $t.find("input:radio").attr("name","data_disk_offering_radio").removeAttr("checked"); $t.find("#name").text("custom:"); $dataDiskOfferingContainer.append($t.show()); @@ -947,25 +947,17 @@ function clickInstanceGroupHeader($arrowIcon) { } - if (currentStepInVmPopup == 5) { //last step + if (currentStepInVmPopup == 5) { //last step + // validate values + var isValid = true; + isValid &= validateString("Name", $thisPopup.find("#wizard_vm_name"), $thisPopup.find("#wizard_vm_name_errormsg"), true); //optional + isValid &= validateString("Group", $thisPopup.find("#wizard_vm_group"), $thisPopup.find("#wizard_vm_group_errormsg"), true); //optional + if (!isValid) return; + // Create a new VM!!!! var moreCriteria = []; moreCriteria.push("&zoneId="+$thisPopup.find("#wizard_zone").val()); - - var name = trim($thisPopup.find("#wizard_vm_name").val()); - if (name != null && name.length > 0) - moreCriteria.push("&displayname="+encodeURIComponent(name)); - - var group = trim($thisPopup.find("#wizard_vm_group").val()); - if (group != null && group.length > 0) - moreCriteria.push("&group="+encodeURIComponent(group)); - - /* - if($thisPopup.find("#wizard_network_groups_container").css("display") != "none" && $thisPopup.find("#wizard_network_groups").val() != null) { - var networkGroupList = $thisPopup.find("#wizard_network_groups").val().join(","); - moreCriteria.push("&networkgrouplist="+encodeURIComponent(networkGroupList)); - } - */ + moreCriteria.push("&templateId="+$thisPopup.find("#step1 .rev_wiztemplistbox_selected").attr("id")); moreCriteria.push("&serviceOfferingId="+$thisPopup.find("input:radio[name=service_offering_radio]:checked").val()); @@ -976,14 +968,22 @@ function clickInstanceGroupHeader($arrowIcon) { else //template diskOfferingId = $thisPopup.find("#data_disk_offering_container input[name=data_disk_offering_radio]:checked").val(); - if(diskOfferingId != null && diskOfferingId != "" && diskOfferingId != "none" && diskOfferingId != "custom") + if(diskOfferingId != null && diskOfferingId != "" && diskOfferingId != "no" && diskOfferingId != "custom") moreCriteria.push("&diskOfferingId="+diskOfferingId); + + var name = trim($thisPopup.find("#wizard_vm_name").val()); + if (name != null && name.length > 0) + moreCriteria.push("&displayname="+encodeURIComponent(name)); + + var group = trim($thisPopup.find("#wizard_vm_group").val()); + if (group != null && group.length > 0) + moreCriteria.push("&group="+encodeURIComponent(group)); vmWizardClose(); var $t = $("#midmenu_item_vm").clone(); $t.find("#vm_name").text("Adding...."); - $t.find("#ip_address_container #label").hide(); + $t.find("#ip_address_container #label").html(" "); $t.find("#content").addClass("inaction"); $t.find("#spinning_wheel").show(); $("#midmenu_container").append($t.show()); @@ -1014,6 +1014,7 @@ function clickInstanceGroupHeader($arrowIcon) { $t.find("#spinning_wheel").hide(); if (result.jobstatus == 1) { // Succeeded + $t.find("#ip_address_container #label").text("IP Address:"); $t.find("#info_icon").removeClass("error").show(); $t.data("afterActionInfo", ("Adding succeeded.")); if("virtualmachine" in result)