buildframework/helium/tools/preparation/ci.ant.xml
changeset 1 be27ed110b50
child 179 d8ac696cc51f
equal deleted inserted replaced
0:044383f39525 1:be27ed110b50
       
     1 <?xml version="1.0" encoding="UTF-8"?>
       
     2 <!-- 
       
     3 ============================================================================ 
       
     4 Name        : ci.ant.xml 
       
     5 Part of     : Helium 
       
     6 
       
     7 Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     8 All rights reserved.
       
     9 This component and the accompanying materials are made available
       
    10 under the terms of the License "Eclipse Public License v1.0"
       
    11 which accompanies this distribution, and is available
       
    12 at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
    13 
       
    14 Initial Contributors:
       
    15 Nokia Corporation - initial contribution.
       
    16 
       
    17 Contributors:
       
    18 
       
    19 Description:
       
    20 
       
    21 ============================================================================
       
    22 -->
       
    23 <project name="ci" xmlns:hlm="http://www.nokia.com/helium">
       
    24     <description>
       
    25     CI related targets
       
    26     </description>
       
    27     
       
    28     <!-- Delete all the folders based on configurations file inside dir-path, optional attribute pool-size's default value is 4 -->
       
    29     <target name="delete-folders-from-list" if = "ci.cleanup.env.dir">
       
    30         <exec osfamily="windows" executable="python" failonerror="true" outputproperty="delete.folders.drive">
       
    31             <arg value="${helium.dir}/tools/common/python/scripts/searchnextdrive.py"/>               
       
    32         </exec>
       
    33         <hlm:deleteFoldersFromDirMacro dir-path="${ci.cleanup.env.dir}" delete-folders-drive="${delete.folders.drive}"/>
       
    34     </target>
       
    35 
       
    36     <!-- Delete all the folders based on configurations file inside dir-path, optional attribute pool-size's default value is 4 -->
       
    37     <scriptdef name="deleteFoldersFromDirMacro" language="jython" uri="http://www.nokia.com/helium">
       
    38         <attribute name="dir-path" />
       
    39         <attribute name="pool-size" />
       
    40         <attribute name="delete-folders-drive" />
       
    41 import os
       
    42 import fileutils
       
    43 import threadpool
       
    44 import subprocess
       
    45 import sys
       
    46 
       
    47 dir_path = str(attributes.get('dir-path'))
       
    48 del_folder_drive = attributes.get('delete-folders-drive')
       
    49 pool_size = attributes.get('pool-size')
       
    50 if pool_size != None:
       
    51     pool_size = str(pool_size)
       
    52 else:
       
    53     pool_size = "4"
       
    54 delete_dirs = []
       
    55 found_inputs = []
       
    56 # Read config files
       
    57 self.log(str("Scanning %s." % dir_path))
       
    58 for path_ in os.listdir(dir_path):
       
    59     self.log(str("Checking %s." % path_))
       
    60     filename = os.path.join(dir_path, path_)
       
    61     if (os.path.isfile(filename)):
       
    62         found_inputs.append(filename)
       
    63         file_ = open(filename)
       
    64         for delete_dir in file_.readlines():
       
    65             delete_dir = os.path.normpath(delete_dir.strip())
       
    66             if (len(delete_dir) > 0) and  os.path.isdir(delete_dir):
       
    67                 delete_dirs.append(delete_dir)
       
    68         file_.close()
       
    69     
       
    70 # Delete all dirs based on config
       
    71 for dir_ in delete_dirs:
       
    72     try:
       
    73         if os.sep == '\\':
       
    74             fileutils.subst(del_folder_drive, dir_)
       
    75             self.log(str("substed for deleling folders"))
       
    76             self.log(str("Removing %s\\" % del_folder_drive))
       
    77             fileutils.rmtree("%s\\" % del_folder_drive)
       
    78             fileutils.unsubst(del_folder_drive)
       
    79             self.log(str("unsbusted substed for deleling folders"))
       
    80         else:
       
    81             self.log(str("Removing %s" % dir_))
       
    82             fileutils.rmtree(dir_)
       
    83     except Exception, e:
       
    84         if os.sep == '\\':
       
    85             fileutils.unsubst(del_folder_drive)
       
    86             self.log(str("unsbusted for deleling folders"))
       
    87         self.log(str("ERROR: %s" % e))
       
    88 
       
    89 # Delete all config files
       
    90 for path_ in found_inputs:
       
    91     self.log(str("Deleting %s." % path_))
       
    92     os.remove(path_)
       
    93     </scriptdef>
       
    94 
       
    95     <!-- Macro for the folders to be deleted in a file based on the folder creation time  
       
    96     If the folders are created at the same time, then it will delete only one of them (this 
       
    97     needs to be handled properly in the future releases if required)-->
       
    98     <scriptdef name="BADeleteMacro" language="jython" uri="http://www.nokia.com/helium">
       
    99         <attribute name="outputdir"/>
       
   100         <attribute name="rootdir"/>
       
   101         <attribute name="no.ba.remain"/>
       
   102         <![CDATA[
       
   103 import os
       
   104 import time
       
   105 ctime_dict = {}
       
   106 root_dir = str(attributes.get('rootdir'))
       
   107 output_dir = str(attributes.get('outputdir'))
       
   108 for dir_ in os.listdir(root_dir):
       
   109     if (os.path.isdir(os.path.join(root_dir, dir_))):
       
   110         dir_ctime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getctime(os.path.join(root_dir, dir_))))
       
   111         ctime_dict[dir_ctime] = dir_
       
   112 ctime_list = ctime_dict.keys()
       
   113 ctime_list.sort()
       
   114 self.log(str("ctime_list: %s" % ctime_list))
       
   115 filename = time.strftime('%Y%m%d%H%M%S', time.localtime())
       
   116 filename = os.path.join(output_dir, filename + '_file_delete.txt')
       
   117 self.log(str("Creating %s" % filename))
       
   118 file_ = open(filename, 'w+')
       
   119 count = len(ctime_list)
       
   120 ba_to_leave = int(str(attributes.get('no.ba.remain')))
       
   121 self.log(str("Leaving %d build areas." % ba_to_leave)) 
       
   122 if (ba_to_leave > 0):
       
   123     for ctime_entry in ctime_list:
       
   124         print count
       
   125         if (ba_to_leave >= count):
       
   126             break
       
   127         file_.write(os.path.join(root_dir, ctime_dict[ctime_entry]) + '\n')
       
   128         count -= 1
       
   129 file_.close()
       
   130         ]]>
       
   131     </scriptdef>
       
   132 
       
   133     <!-- This target flags the Build areas for deletion. So the cleanup build robot could remove them. -->
       
   134     <target name="flag-ba-for-deletion" if = "ci.cleanup.env.dir">
       
   135         <mkdir dir="${ci.cleanup.env.dir}"/>
       
   136         <if>
       
   137             <not>
       
   138                 <isset property="ci.min.ba.maintain"/>
       
   139             </not>
       
   140             <then>
       
   141                 <property name="ci.min.ba.maintain" value="2"/>
       
   142             </then>
       
   143         </if>
       
   144         <hlm:BADeleteMacro outputdir="${ci.cleanup.env.dir}" rootdir="${prep.root.dir}" no.ba.remain="${ci.min.ba.maintain}"/>
       
   145     </target>
       
   146     
       
   147     <!-- This task monitor the sessions available under the session file and update/create new ones if needed. -->
       
   148     <scriptdef name="monitorCCMSession" language="jython" uri="http://www.nokia.com/helium">
       
   149         <attribute name="delivery"/>
       
   150         <attribute name="sessionfile"/>
       
   151 import ccm
       
   152 import nokia.nokiaccm
       
   153 import configuration
       
   154 import os
       
   155 import logging
       
   156 import traceback
       
   157 logging.basicConfig(level=logging.INFO)
       
   158 
       
   159 databases = []
       
   160 delivery = str(attributes.get('delivery'))
       
   161 sessionFile = str(attributes.get('sessionfile'))
       
   162 configBuilder = configuration.NestedConfigurationBuilder(open(delivery, 'r'))
       
   163 configSet = configBuilder.getConfiguration()
       
   164 for config in configSet.getConfigurations():
       
   165     if config['database'] not in databases:
       
   166         databases.append(config['database'])
       
   167 
       
   168 config = configuration.PropertiesConfiguration()
       
   169 if os.path.exists(sessionFile):
       
   170     self.log(str("Opening the file %s..." % sessionFile))
       
   171     config.load(open(sessionFile, 'r'))
       
   172 else:
       
   173     self.log(str("File %s will be created..." % sessionFile))
       
   174         
       
   175 for database in databases:
       
   176     self.log(str("Checking %s..." % database))
       
   177     update_session = True
       
   178     if config.has_key(database):
       
   179         sessionid = config[database]
       
   180         # test if valid
       
   181         self.log(str("Is session %s still valid?..." % sessionid))
       
   182         if ccm.session_exists(sessionid, database=database):
       
   183             self.log(str("Yes."))
       
   184             update_session = False
       
   185 
       
   186     if update_session:
       
   187         try:
       
   188             self.log(str("Opening a new session for %s..." % database))
       
   189             session = nokia.nokiaccm.open_session(database=database)
       
   190             session.close_on_exit = False        
       
   191             config[database] = session.addr()
       
   192         except Exception, exc:
       
   193             traceback.print_exc()
       
   194             raise exc
       
   195     
       
   196 self.log(str("Updating the file %s..." % sessionFile))
       
   197 config.store(open(sessionFile, 'w+'))    
       
   198     </scriptdef>
       
   199 
       
   200     <!-- Task that generates an XML configuration of the work that will be done by ccm-get-input. -->
       
   201     <macrodef name="findProjects" uri="http://www.nokia.com/helium">
       
   202         <attribute name="delivery"/>
       
   203         <attribute name="sessionfile"/>
       
   204         <attribute name="output"/>
       
   205         <sequential>
       
   206             <hlm:python>
       
   207 import ccm
       
   208 import configuration
       
   209 import os
       
   210 import logging
       
   211 import amara
       
   212 
       
   213 logging.basicConfig(level=logging.INFO)
       
   214 
       
   215 delivery = str(r'@{delivery}')
       
   216 sessionFile = str(r'@{sessionfile}')
       
   217 outputFilename = str(r'@{output}')
       
   218         
       
   219 sconfig = configuration.PropertiesConfiguration()
       
   220 
       
   221 print "Opening the file %s..." % sessionFile
       
   222 sconfig.load(open(sessionFile, 'r'))
       
   223 
       
   224 configBuilder = configuration.NestedConfigurationBuilder(open(delivery, 'r'))
       
   225 configSet = configBuilder.getConfiguration()
       
   226 projects = []        
       
   227 for config in configSet.getConfigurations():        
       
   228     if config.type == "checkout" and not config.get_boolean('skip.ci', False): 
       
   229         try:
       
   230             sessionid = sconfig[config['database']]
       
   231             session = ccm.Session(None, None, None, ccm_addr=sessionid, close_on_exit=False)
       
   232             ccmproject = session.create(config.name)
       
   233             wapath = os.path.join(config['dir'], ccmproject.name, ccmproject.name)
       
   234             result = session.get_workarea_info(wapath)
       
   235             print "Found wa for project %s." % result['project'].objectname
       
   236             if config.has_key('ci.custom.query'):
       
   237                 projects.append({u'database': unicode(config['database']), u'action': u'checkout', u'name': unicode(result['project'].objectname), u'customQuery': unicode(config['ci.custom.query'])})
       
   238             else: 
       
   239                 projects.append({u'database': unicode(config['database']), u'action': u'checkout', u'name': unicode(result['project'].objectname)})    
       
   240         except ccm.CCMException, exc:
       
   241             projects.append({u'database': unicode(config['database']), u'action': u'to_be_checkout', u'name': unicode(config.name)})
       
   242     elif config.type == "snapshot" and not config.get_boolean('skip.ci', False):
       
   243         sessionid = sconfig[config['database']]
       
   244         session = ccm.Session(None, None, None, ccm_addr=sessionid, close_on_exit=False)
       
   245         ccmproject = session.create(config.name)
       
   246         versionfile = os.path.join(config['dir'], ccmproject.name, 'project.version')
       
   247         if (os.path.exists(versionfile)):
       
   248             stream = open(versionfile, "r")
       
   249             projectname = stream.read().strip()
       
   250             stream.close()
       
   251             if (projectname != config.name):
       
   252                 if config.has_key('ci.custom.query'):
       
   253                     projects.append({u'database': unicode(config['database']), u'action': u'snapshot_update', u'name': unicode(config.name), u'customQuery': unicode(config['ci.custom.query'])})
       
   254                 else:
       
   255                     projects.append({u'database': unicode(config['database']), u'action': u'snapshot_update', u'name': unicode(config.name)})
       
   256         else:
       
   257             if config.has_key('ci.custom.query'):
       
   258                 projects.append({u'database': unicode(config['database']), u'action': u'snapshot', u'name': unicode(config.name), u'customQuery': unicode(config['ci.custom.query'])})
       
   259             else:    
       
   260                 projects.append({u'database': unicode(config['database']), u'action': u'snapshot', u'name': unicode(config.name)})
       
   261 
       
   262 doc = amara.create_document()
       
   263 root = doc.xml_create_element(u"config")
       
   264 doc.xml_append(root)
       
   265 
       
   266 for project in projects:
       
   267     p = doc.xml_create_element(u"project", attributes=project)
       
   268     root.xml_append(p)
       
   269         
       
   270 output = open(outputFilename, "w+")
       
   271 output.write(doc.xml())
       
   272 output.close()
       
   273             </hlm:python>
       
   274         </sequential>
       
   275     </macrodef>
       
   276 
       
   277     <!-- Validate input for the ci-monitor-ccm-session target -->
       
   278     <target name="ci-monitor-ccm-session-validate" depends="ccm-prepare-input">
       
   279         <if>
       
   280             <and>
       
   281                 <available file="${prep.delivery.conf.parsed}"/>
       
   282                 <isset property="ci.session.file"/>                
       
   283                 <isset property="run.ccm"/>
       
   284             </and>
       
   285             <then>
       
   286                 <property name="do.ci-monitor-ccm-session" value="true"/>
       
   287             </then>
       
   288             <else>
       
   289                 <echo>Delivery file not available or 'ci.session.file' not defined or ccm.enabled not set to true.</echo>
       
   290             </else>
       
   291         </if>
       
   292     </target>
       
   293     
       
   294     <!-- Validate input for the ci-prep-wa-create-list target. --> 
       
   295     <target name="ci-prep-wa-create-list-validate" depends="ci-monitor-ccm-session-validate" if="do.ci-monitor-ccm-session">
       
   296         <if>
       
   297             <and>
       
   298                 <isset property="ci.project.config"/>             
       
   299             </and>
       
   300             <then>
       
   301                 <property name="do.ci-prep-wa-create-list" value="true"/>
       
   302             </then>
       
   303             <else>
       
   304                 <echo>'ci.project.config' not defined.</echo>
       
   305             </else>
       
   306         </if>
       
   307     </target>
       
   308 
       
   309     <!-- Bootstrapper target for Cruise Control. It generates a session file compatible with CCM task. -->
       
   310     <target name="ci-monitor-ccm-session" depends="ci-monitor-ccm-session-validate" if="do.ci-monitor-ccm-session">
       
   311         <hlm:monitorCCMSession delivery="${prep.delivery.conf.parsed}" sessionfile="${ci.session.file}"/>
       
   312     </target>
       
   313 
       
   314     <!-- Bootstrapper target for Cruise Control. This target output the future work that ccm-get-input will be doing. -->
       
   315     <target name="ci-prep-wa-create-list" depends="ci-prep-wa-create-list-validate" if="do.ci-prep-wa-create-list">
       
   316         <hlm:findProjects delivery="${prep.delivery.conf.parsed}" sessionfile="${ci.session.file}" output="${ci.project.config}"/>
       
   317     </target>
       
   318 
       
   319 </project>