Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6914 dpurdie 1
package com.erggroup.buildtool.abt;
2
 
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.io.FileOutputStream;
6
import java.io.FileWriter;
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.Iterator;
10
import java.util.Properties;
11
 
12
import org.apache.log4j.Logger;
13
import org.apache.tools.ant.BuildException;
14
import org.apache.tools.ant.Project;
15
import org.apache.tools.ant.Target;
16
import org.apache.tools.ant.Task;
17
import org.apache.tools.ant.taskdefs.Execute;
18
import org.apache.tools.ant.taskdefs.Redirector;
19
 
20
import com.erggroup.buildtool.abt.RemoteExecution.LogOutput;
21
import com.erggroup.buildtool.smtp.CreateUrls;
22
import com.erggroup.buildtool.smtp.Smtpsend;
23
import com.erggroup.buildtool.utilities.CommandBuilder;
24
import com.erggroup.buildtool.utilities.ElapseTime;
25
import com.erggroup.buildtool.utilities.utilities;
26
 
27
public class ABT extends Task
28
{
29
    private String ls = System.getProperty( "line.separator" );
30
    private String gbeMachtype = System.getenv("GBE_MACHTYPE");
31
    private String dpkgArchive = System.getenv("GBE_DPKG");
32
    private String hostname = System.getenv("GBE_HOSTNAME");
33
    private String gbeMachClass;          // Escrow Only
34
 
35
    // ant built in
36
    private Project project;
37
    private String basedir;
38
 
39
    // global
40
    private boolean master = false;
41
    private String gbebuildfilter;
42
    private String mailServer;
43
    private String mailSender;
44
 
45
    // project related
46
    private String rtagId;
47
    private String daemon;
48
    private String release;
49
    private String buildtoolVersion;
50
    private String family;
51
    private String oldExtension;
52
    private String newExtension;
53
    private ABTData abtData;
54
 
55
    // target related
56
    private Target target;
57
    private String packageVersionID;
58
    private String packageAlias;
59
    private String packageName;
60
    private String packageVersion;
61
    private String packageFullVersion;
62
    private String packageExtension;
63
    private String packageLoc;
64
    private String packageVcsTag;
65
    private String directChange;
66
    private String doesNotRequireSourceControlInteraction;
67
    private boolean isaRipple;
68
    private int testBuildInstruction = 0;
69
    private boolean generic = false;
70
    private boolean packageTarBall = false;
71
    private boolean useTestArchive = false;
72
    private String loc;
73
    private String unittests;
74
    private ArrayList<Depend> dependCollection = new ArrayList<Depend> ();
75
    private ArrayList<BuildInfo> buildInfoCollection = new ArrayList<BuildInfo>();
76
    private StringBuilder owners = new StringBuilder();;
77
    private Machine mMachine;
78
    private String logBase;
79
 
80
    // set up in execute
81
    private BuildStandards packageStandard = BuildStandards.NONE;           // Build standard for the package
82
    private BuildStandards buildStandard = BuildStandards.NONE;             // Build Standard for this instance
83
    private JavaVersions javaVersion = JavaVersions.NONE;
84
    private CompileTargets compileTarget = CompileTargets.NONE;
85
    // abt task result property
86
    private String propertyValue = "0";
87
    // output redirector
88
    private Redirector re;
89
    private File output;
90
    // exec thread
91
    private CommandBuilder command = new CommandBuilder();
92
    private String cwd;
93
    private Execute thread;
94
    private File wd;
95
    private String newVcsTag;
96
    private static final Logger mLogger = Logger.getLogger(ABT.class);
97
    private boolean fullyPublished = false;
98
 
99
    private static final char DEBUG = 0;
100
    private static final char INFO = 1;
101
    private static final char WARN = 2;
102
    private static final char ERROR = 3;
103
    private static final char FATAL = 4;
104
 
105
    //  Simple class to contain error information to be reported to the user
106
    private class ErrorInfo {
107
        String cmd;
108
        int result;
109
        String error;
110
 
111
        public ErrorInfo (String error)
112
        {
113
            this.error = error;
114
        }
115
 
116
        public ErrorInfo(String cmd, int result, String error)
117
        {
118
            this.cmd = cmd;
119
            this.result = result;
120
            this.error = error;
121
        }
122
 
123
        public String toString()
124
        {
125
            String rv = error;
126
            if (cmd != null)
127
            {
128
                rv += " : " + cmd;
129
                rv += " returned " + result;
130
            }
131
            return rv;
132
        }
133
 
134
        public String toHtml() {
135
            String rv = "Error : " + error;
136
            if (cmd != null)
137
            {
138
                rv += "<br>Command : " + cmd;
139
                rv += "<br>Returned: " + result;
140
            }
141
            return rv;
142
        }
143
    }
144
 
145
    /** Log a message to two locations
146
     *  1) log4j application wide log - using facility
147
     *  2) Ant Command output log - always
148
     * 
149
     * @param message   - Message to log
150
     * @param facility  - Log level
151
     */
152
    private void logMsg(String message, char facility)
153
    {
154
        if ( daemon != null )
155
        {
156
            if ( facility == DEBUG)
157
            {
158
                mLogger.debug(message);
159
            }
160
            else if ( facility == INFO)
161
            {
162
                mLogger.info(message);
163
            }
164
            else if ( facility == WARN)
165
            {
166
                mLogger.warn(message);
167
            }
168
            else if ( facility == ERROR)
169
            {
170
                mLogger.error(message);
171
            }
172
            else
173
            {
174
                mLogger.fatal(message);
175
            }
176
        }
177
 
178
        log( message );
179
    }
180
 
181
    /** Log two strings as 'info'
182
     *  The two strings are simply concatenated.
183
     * 
184
     * @param message1  - First part of the message
185
     * @param message2  - Second part of the message
186
     */
187
    private void logMsg(String message1, String message2)
188
    {
189
        logMsg( message1 + message2, INFO );
190
    }
191
 
192
 
193
    /** Add package location options
194
     *  Options depend on the build standard in use
195
     */
196
    private void addCommandLocate()
197
    {
198
        if ( packageStandard == BuildStandards.ANT )
199
        {
200
            command.add( "-locatefile=" + packageName + ".xml" );
201
        }
202
        else
203
        {
204
            command.add( "-locatepkg=" + packageLoc );
205
        }
206
    }
207
 
208
 
209
    /** Execute the command currently being assembled
210
     *  Logs command, exit code and execution duration
211
     * 
212
     * @param message           - Null: Don't report errors, otherwise text to prepend to the reported error
213
     * @return                  - Return code from the executed command
214
     * @throws Exception
215
     */
216
    private int runCommand( String message ) throws Exception
217
    {
218
        ElapseTime et = new ElapseTime();
219
 
220
        //  Need to create a cmd array with exactly the required number of arguments
221
        //  thread.setCommandline() cannot handle null items in the array
222
        //  Create a single logMessage while processing the array
223
        String logMessage = command.toString();
224
        logMsg( logMessage, WARN );
225
 
226
        thread.setCommandline(command.getArray());
227
        int retVal = thread.execute();
228
 
229
        //  Report error conditions 
230
 
231
        if ( retVal == Execute.INVALID )
232
        {
233
            reportErrorException( "Failure to execute thread, internal ABT problem", 256 );
234
        }
235
        else
236
        {
237
            logMsg( "command returned: "+ retVal  + ", elapsed time (S): " + et.toString(), WARN);
238
 
239
            if ( message != null && retVal != 0 )
240
            {
241
                ErrorInfo errorData = new ErrorInfo(command.toString() , retVal, message );
242
                reportErrorException( errorData, retVal );
243
            }
244
        }
245
 
246
        return retVal;
247
    }
248
 
249
    /**
250
     * Check that one marker file has been published into dpkg_archive 
251
     * Assumption - not called in Escrow Mode 
252
     * 
253
     * @param archive     - Archive to test
254
     * @param tag         - Marker suffix
255
     * 
256
     * @return true if the package is published 
257
     */
258
    private boolean checkPublished(String archive, String tag) throws Exception
259
    {
260
        if (archive == null)
261
        {
262
            reportErrorException( "GBE_DPKG environment variable not set", 256 );
263
        }
264
 
265
        String filename = "built." + tag;
266
        String destination = utilities.catDir(archive, packageName,  packageFullVersion); 
267
 
268
        //
269
        //  Have been having issues with NFS caching
270
        //  Current attempt is to flush NFS caches using freshFile(), but at the moment
271
        //  the code will still retry a number of time. This 'should' not be required if the
272
        //  flushing code is operational.
273
        //
274
        //  Insert log info if we have tried more than once
275
        //  Idea is to monitor first time failures and then delete this code
276
        //
277
 
278
        boolean found = false;
279
        int   maxwait = 2 * 4;
280
        for ( int ii = 0; ii < maxwait && !found; ii++)
281
        {
282
            found = utilities.freshFileExists(utilities.catDir(destination, filename));
283
            if ( !found )
284
            {
285
                // Debug - display files in the 
286
                try
287
                {
288
                    String files;
289
                    File folder = new File(destination);
290
                    File[] listOfFiles = folder.listFiles();
291
                    if ( listOfFiles == null )
292
                    {
293
                        logMsg( "published. Destination not a dir: " + destination, FATAL );
294
                    }
295
                    else
296
                    {
297
                        for (int i = 0; i < listOfFiles.length; i++) 
298
                        {
299
                            if (listOfFiles[i].isFile())
300
                            {
301
                                files = listOfFiles[i].getName();
302
                                logMsg("published. DirContent:" + files , WARN);
303
                            }
304
                        }
305
                    }
306
                }
307
                catch( Exception e )
308
                {
309
                    logMsg( "published. Display files caught Exception:" + e.getMessage(), FATAL );
310
                }
311
 
312
 
313
                Thread.sleep(500);
314
                logMsg("published. Wait for " + filename + ".(" + ii +")" , WARN);
315
            }
316
        }
317
 
318
        if ( found )
319
        {
320
            logMsg("published. " + filename + " exists", WARN);
321
        }
322
        else
323
        {
324
            logMsg("published. " + filename + " does not exist", WARN);
325
        }
326
 
327
        return found;
328
    }
329
 
330
    /** Print a line of text to a file
331
     * 
332
     * @param file  - FileWrite to print to
333
     * @param msg1  - Text to write. Will append line separator
334
     * @throws IOException
335
     */
336
    private void printPackage( FileWriter file, String msg1 ) throws IOException
337
    {
338
        file.write( msg1 + ls );
339
    }
340
 
341
    /** Copy a file
342
     * 
343
     * @param source    - Source File
344
     * @param dest      - Target File
345
     */
346
    private void copyFile( File source, File dest )
347
    {
348
        if ( source.exists() )
349
        {
350
            try
351
            {
352
                FileInputStream fis = new FileInputStream(source);
353
                FileOutputStream fos = new FileOutputStream(dest);
354
                byte[] buf = new byte[1024];
355
                int i = 0;
356
                while( (i=fis.read(buf)) != -1)
357
                {
358
                    fos.write(buf, 0, i);
359
                }
360
                fis.close();
361
                fos.close();
362
            }
363
            catch( Exception e )
364
            {
365
                logMsg( "copyFile caught Exception", ERROR );
366
            }
367
        }
368
    }
369
 
370
    /** Save the log file
371
     *  <br>Used on error build
372
     *  <br>Used on complete build
373
     * 
374
     * @return  True: Can log ( Daemon mode)
375
     */
376
 
377
    private boolean saveLogs()
378
    {
379
        if ( daemon == null )
380
        {
381
            // do nothing more in escrow
382
            return false;
383
        }
384
 
385
        // persist the failure log to GBE_LOG/hostname/rtagid/daemon
386
        String log = System.getenv("GBE_LOG");
387
 
388
        if ( log == null )
389
        {
390
            // cannot happen, GBE_LOG is checked in BuildDaemon at startup
391
            return false;
392
        }
393
 
394
        File destinationLog = new File( log );
395
        File destinationHostname = new File( destinationLog, hostname );
396
        File destinationRtagId = new File( destinationHostname, rtagId );
397
        // create directories
398
        new File( destinationRtagId, daemon).mkdirs();
399
 
400
        File destinationDaemon = new File( destinationRtagId, daemon );
401
 
402
        if ( destinationDaemon.exists() )
403
        {
404
            File buildsource = new File(rtagId + "build.xml");
405
            File buildcopy = new File( destinationDaemon, logBase + ".xml");
406
            copyFile( buildsource, buildcopy );
407
 
408
            File logsource = new File(rtagId + ".log");
409
            File logcopy = new File( destinationDaemon, logBase + ".log");
410
            copyFile( logsource, logcopy );
411
 
412
            logMsg("reportError persisting " + logcopy.getName(), WARN);
413
        }
414
 
415
        return true;
416
    }
417
 
418
    private void reportError(String error, int retVal)
419
    {
420
        reportError( new ErrorInfo(error), retVal);
421
    }
422
    private void reportError(ErrorInfo error, int retVal)
423
    {
424
        propertyValue = String.valueOf( retVal );
425
 
426
        logMsg( error.toString(), ABT.ERROR );
427
        logMsg( "reportError propertyValue = " + propertyValue + ", ", error.toString());
428
 
429
        //  Save the logs
430
        //      Will return false in situations were we can't proceed
431
        if ( ! saveLogs() )
432
        {
433
            return;
434
        }
435
 
436
        //  Only send emails if we have all the bits required
437
        //  Will not get this far unless we are in daemon mode
438
        if ( owners.length() > 0 && mailServer != null && mailSender != null )
439
        {
440
 
441
            String href = hostname + "/" + rtagId + "/" + daemon + "/" + logBase + ".log"; 
442
            String unc =  CreateUrls.generateUncBaseUrl() + "/" + href;
443
 
444
            String body = "Release: " + release + "<p>" +
445
                   "Package: " + packageName + "<p>" + 
446
                   "RM link: " + CreateUrls.generateRmUrl(rtagId,packageVersionID) + "<p>" +
447
                   "Build machine: " + hostname + "<p>" +
448
                   "Machine type: " + gbeMachtype + "<p>" +
449
                   error.toHtml() + "<p>" +
450
                   "Log file: <a href=\"" + unc + "\">" + href + "</a> ... URL expires in 5 working days time<p><hr>";
451
 
452
            try
453
            {
454
                Smtpsend.send( mailServer,          // mailServer
455
                               mailSender,          // source
456
                               owners.toString(),   // target
457
                               null,                // cc
458
                               null,                // bcc
459
                               "BUILD FAILURE on package " + packageName, // subject
460
                               body,                // body
461
                               null                 // attachment
462
                        );
463
            }
464
            catch( Exception e )
465
            {
466
                // not fatal
467
                logMsg( "reportError caught Exception", WARN);
468
            }
469
        }
470
 
471
    }
472
 
473
    private void reportErrorException(String error, int retVal) throws Exception
474
    {
475
        reportError( error, retVal );
476
        throw new Exception( hostname );
477
    }
478
 
479
    private void reportErrorException(ErrorInfo error, int retVal) throws Exception
480
    {
481
        reportError( error, retVal );
482
        throw new Exception( hostname );
483
    }
484
 
485
    /**
486
     * Init the metrics generation process
487
     * 
488
     * @exception Exception
489
     */
490
    private void metricsBegin() throws Exception
491
    {
492
        if ( master )
493
        {
494
            // gather metrics
495
            // jats -locatefile=.jats.packageroot etool jats_metrics -mode=init -rootdir=.
496
            // -locate=.jats.packageroot causes jats to cd to the folder containing the file .jats.packageroot
497
            // this file is created in the -path folder by jats release -extract
498
            // DEVI 51370 it is essential for metrics branch calculation the metrics utility is started within a static view
499
            //
500
            command.init("jats" );
501
            command.add( "-locatefile=.jats.packageroot" );
502
            command.add( "etool", "jats_metrics" );
503
            command.add( "-mode=init" );
504
            command.add( "-rootdir=." );
505
 
506
            runCommand( "Failure to collect metrics" );
507
        }     
508
    }
509
 
510
    /**
511
     * Complete the metrics generation process
512
     * 
513
     * @exception Exception
514
     */
515
    private void metricsEnd() throws Exception
516
    {
517
        if ( master )
518
        {
519
            File metrics = new File(utilities.catDir(basedir, rtagId + "abtmetrics.txt"));
520
            if ( metrics.exists() )
521
            {
522
                metrics.delete();
523
            }
524
 
525
            // gather metrics
526
            // jats -locatefile=.jats.packageroot etool jats_metrics -mode=finish -out=abtmetrics.txt
527
            command.init("jats" );
528
            command.add( "-locatefile=.jats.packageroot" );
529
            command.add( "etool", "jats_metrics" );
530
            command.add( "-mode=finish" );
531
            command.add( "-out=" + metrics.getAbsolutePath() );
532
 
533
            runCommand( "Failure to collect metrics" );
534
        }    
535
    }
536
 
537
    /**
538
     * Generate the build dependency data file.
539
     * 
540
     * @exception Exception
541
     */
542
    private void genbuild() throws Exception
543
    {
544
 
545
        //
546
        //  Create build files with updated dependency information
547
        //  In escrow mode : No new dependency information
548
        //  In daemon mode :
549
        //      Ripple     : New dependency information
550
        //      Verify     : Existing dependency information
551
        //
552
        //  In all modes  : ANT builds need an auto.xml
553
        //
554
        //  In order to create auto.xml/auto.pl with package dependencies need to
555
        //  create file with dependency data (auto.cfg) only because its
556
        //  needed by "jats_rewrite"
557
        //
558
        File cfg = null;
559
        boolean  createFile = false;
560
        if ( daemon != null )
561
        {
562
            createFile = true;
563
 
564
            // always generate auto.cfg
565
            cfg = new File( utilities.catDir(cwd, "auto.cfg"));
566
            cfg.createNewFile();
567
 
568
            if ( !cfg.exists() || !cfg.canWrite() )
569
            {
570
                reportErrorException( "Failed to open auto.cfg", 263 );
571
            }
572
 
573
            try
574
            {
575
                FileWriter cfgfw = new FileWriter(cfg);
576
                printPackage( cfgfw, packageName + " " + packageFullVersion );
577
 
578
                // provide releasemanager.projectname=<name[0]> and releasemanager.releasename=<name[1]>
579
                String[] name = release.split( " > ", 2 );
580
 
581
                if ( name.length == 2 )
582
                {
583
                    printPackage( cfgfw, "releasemanager.projectname=" + name[0] );
584
                    printPackage( cfgfw, "releasemanager.releasename=" + name[1] );
585
                }
586
 
587
                for (Iterator<Depend> it=dependCollection.iterator(); it.hasNext(); )
588
                {
589
                    Depend depend = it.next();
590
                    printPackage( cfgfw, depend.getPackage_Alias() );
591
                }
592
 
593
                cfgfw.close();
594
            }
595
            catch( IOException e )
596
            {
597
                reportErrorException( "Failure to write to auto.cfg", 263 );
598
            }
599
        }
600
        else
601
            if ( packageStandard == BuildStandards.ANT )
602
            {
603
                // Have not created an auto.xml with updated dependencies
604
                // Ant build still would like an auto.xml file
605
                //
606
                // ie packages with a line <import file="auto.xml" optional="true"/> are fine
607
                //    but in escrow and rebuild we still need an auto.xml to be kind
608
                //
609
                createFile = true;
610
            }
611
 
612
        //
613
        //  Create the auto.pl/auto.xml file if required
614
        //
615
        if ( createFile )
616
        {
617
            command.init("jats");
618
            addCommandLocate();
619
            command.add( "etool", "jats_rewrite" );
620
 
621
            if ( packageStandard == BuildStandards.ANT )
622
            {
623
                command.add( "-infile=" + packageName + "depends.xml" );
624
                command.add( "-outfile=auto.xml" );
625
            }
626
            else
627
            {
628
                command.add( "-infile=build.pl" );
629
                command.add( "-outfile=auto.pl" );
630
            }
631
 
632
            if ( cfg != null && daemon != null)
633
            {
634
                command.add( "-config=" + cfg.getAbsolutePath() );
635
 
636
                //  Validate the Release Manager versions against those in the build files
637
                //  Only do this in daemon mode for:
638
                //      We are rebuilding the package
639
                //          This is detected as: Not have VCS interaction AND is not a test Build
640
                boolean isaRebuild = doesNotRequireSourceControlInteraction != null && testBuildInstruction == 0;
641
                command.add(isaRebuild, "-validate");
642
 
643
                //  Ensure that we don't have excessive packages in the Metadata
644
                //  Only do this in daemon mode, for 'new' or 'test' builds
645
                //  Don't do for:
646
                //      Escrow builds - they can't fix it
647
                //      Ripple builds - it will break a lot of stuff
648
                //      Rebuilds      - it will break stuff
649
                // Do for:
650
                //      New Versions  - User can fix it
651
                //      Test Builds   - User can fix it
652
                boolean isaTestBuild = doesNotRequireSourceControlInteraction != null && testBuildInstruction > 0;
653
                boolean isaNewVersion = !isaRipple && !isaRebuild && !isaTestBuild;
654
                command.add( isaNewVersion || isaTestBuild, "-errors");
655
 
656
            }
657
            else
658
            {
659
                command.add( "-noconfig");
660
            }
661
 
662
            if ( oldExtension != null )
663
            {
664
                command.add( "-oldproject", oldExtension );
665
                command.add( "-newproject", newExtension );
666
            }
667
 
668
            runCommand( "Failure to generate build dependency information. Potentially caused by a mismatch between build files and Release Manager database" );
669
        }
670
    }
671
 
672
    /**
673
     * Build the package
674
     * 
675
     * @exception Exception
676
     */
677
    private void jatsBuildPackage() throws Exception
678
    {
679
        //--------------------------------------------------------------------------
680
        //  Wait for package replication and caching
681
        //      If there is a GBE_DPKG_REPLICA, then there may be a delay between
682
        //      a package being built and the package being available on the replica
683
        //      We need to wait for the required packages to replicate
684
        //
685
        //      If there is a GBE_DPKG_CACHE, then we need to cache the package
686
        //      into the local store - mostly for windows as it seriously speeds
687
        //      up the builds.
688
 
689
        Boolean hasReplica = System.getenv("GBE_DPKG_REPLICA") != null;
690
        Boolean hasCache   = System.getenv("GBE_DPKG_CACHE") != null;
691
 
692
        if (daemon != null && (hasReplica || hasCache)  && !dependCollection.isEmpty())
693
        {
694
            /*
695
             * Limit the command line length provided to the following utility
696
             * Very very long dependency lists may over fill the command line
697
             */
698
            Iterator<Depend> it=dependCollection.iterator();
699
            while( it.hasNext() )
700
            {
701
 
702
                command.init( "jats", "etool", "cache_dpkg");
703
                command.add( hasReplica, "-wait" );
704
 
705
                // ANT builds require the package to be cached
706
                // JATS does not - if its needed it will be done later
707
                command.add( buildStandard != BuildStandards.ANT , "-nocache");
708
 
709
                // Add PackageName/PackageVersion
710
                for (int maxArgs = 0; maxArgs < 10 && it.hasNext(); maxArgs++ )
711
                {
712
                    Depend depend = it.next();
713
                    command.add(depend.getPackageNameVersion());
714
                }
715
 
716
                // Run the command - don't care if it fails
717
                runCommand( null );
718
            }
719
        }
720
 
721
        //--------------------------------------------------------------------------
722
        //  Build Phase
723
        //  Create build environment
724
 
725
        command.init( "jats" );
726
        command.add( gbebuildfilter != null ,"-buildfilter", gbebuildfilter);
727
        addCommandLocate();
728
 
729
        if ( buildStandard == BuildStandards.ANT )
730
        {
731
            command.add( "abt" );
732
            command.add( "-java=" + javaVersion.getJavaVersion() );
733
            command.add( "-buildfile=" + packageName + ".xml" );
734
            command.add( "build" );
735
        }
736
        else
737
        {
738
            command.add( "build", "--package" );
739
 
740
            // Daemon: Sanity check the building of Generic packages
741
            // Escrow: Allow this error - for backward compatibility
742
            if ( daemon != null )
743
            {
744
                if (generic) 
745
                    command.add( "-generic" );
746
                else
747
                    command.add( "-nogeneric" );
748
            }
749
 
750
            // Cache packages into a machine-local archive
751
            //  Will only do this if the package is really built
752
            //
753
            command.add(hasCache, "--cache" );
754
        }
755
 
756
        runCommand( "Failure to set up sandbox" );
757
 
758
        //--------------------------------------------------------------------------
759
        //  Make Package phase
760
        //  Create the package (make)
761
 
762
        command.init("jats" );
763
        command.add( gbebuildfilter != null, "-buildfilter", gbebuildfilter);
764
        addCommandLocate();
765
 
766
        if ( buildStandard == BuildStandards.ANT )
767
        {
768
            command.add( "abt" );
769
            command.add( "-java=" + javaVersion.getJavaVersion() );
770
            command.add( "-buildfile=" + packageName + ".xml" );
771
            command.add( "make_package" );
772
        }
773
        else
774
        {
775
            command.add( "make", "NODEPEND=1" );
776
 
777
            if ( compileTarget == CompileTargets.PROD )
778
            {
779
                command.add( "prod", "package_prod" );
780
            }
781
            else if ( compileTarget == CompileTargets.DEBUG )
782
            {
783
                command.add( "debug", "package_debug" );
784
            }
785
            else
786
            {
787
                command.add( "all" );
788
            }
789
        }
790
 
791
        runCommand( "Failure to generate derived files" );
792
 
793
 
794
        //--------------------------------------------------------------------------
795
        //  Unit tests phase
796
        //  Run autonomous unit tests
797
 
798
        if ( unittests != null )
799
        {
800
            command.init("jats" );
801
            command.add( gbebuildfilter != null, "-buildfilter", gbebuildfilter);
802
            addCommandLocate();
803
 
804
            if ( buildStandard == BuildStandards.ANT )
805
            {
806
                command.add( "abt" );
807
                command.add( "-java=" + javaVersion.getJavaVersion() );
808
                command.add( "-buildfile=" + packageName + ".xml" );
809
                command.add( "run_tests" );
810
            }
811
            else
812
            {
813
                command.add( "make" );
814
                if ( compileTarget == CompileTargets.PROD )
815
                {
816
                    command.add( "run_unit_tests_prod" );
817
                }
818
                else if ( compileTarget == CompileTargets.DEBUG )
819
                {
820
                    command.add( "run_unit_tests_debug" );
821
                }
822
                else
823
                {
824
                    command.add( "run_unit_tests" );
825
                }
826
            }
827
 
828
            runCommand( "Failure to run unit tests" );
829
        }
830
 
831
        //--------------------------------------------------------------------------
832
        //  create_dpkg phase
833
        //  Publish the package to dpkg_archive
834
        //
835
 
836
        command.init("jats" );
837
        addCommandLocate();
838
        command.add( "create_dpkg", "-m" );
839
        command.add( packageTarBall, "-tarmode");
840
        command.add( generic, "-generic" );
841
        command.add( "-pname", packageName );
842
        command.add( "-pversion", packageFullVersion );
843
 
844
        runCommand( "Failure to publish to archive" );
845
 
846
        insertEscrowMarker();
847
    }
848
 
849
    /** Skip Build an ANT Package 
850
     *  Only used on ANT based builds in which it has been determined that another machine
851
     *  is performing the build.
852
     *  
853
     *  Insert required marker files to indicate that the build has occurred
854
     *  Perform this using JATS commands to ensure correct creation of the marker files
855
     *  Basically, a dummy publish phase
856
     *  
857
     *  Note: Skip Builds cannot be generic
858
     *  
859
     */
860
    private void jatsSkipPackage() throws Exception
861
    {
862
        command.init( "jats" );
863
        command.add( "-here" );
864
        command.add( "create_dpkg", "-m" );
865
        command.add( packageTarBall, "-tarmode");
866
        command.add( "-noBuild" );
867
        command.add( "-pname", packageName );
868
        command.add( "-pversion", packageFullVersion );
869
 
870
        runCommand( "Failure to (skip)publish to archive" );
871
    }
872
 
873
    /**   Check if the package has been Published on all the required machines
874
     *    If its a 'generic' package then a tag of built.generic will have been placed in the package
875
     *    Otherwise each build machine will place a built.<MachName> file in the package when
876
     *    its build is completed successfully.
877
     *  
878
     *    If we don't have a complete set of 'built' files, then the package failed to build
879
     *    on one or more platforms. The assumption is that the build failure has been reported
880
     *    by the build daemon.
881
     *  
882
     *    All we know is which MachTypes we build for. This needs to be expanded into
883
     *    a list of MachineNames. Thus a build-set with multiple machines of the same MachType
884
     *    can indicate build failures.
885
     */
886
    private void puplishPackage() throws Exception
887
    {  
888
        //  If the package fragments are being delivered as tarballs then they needs to be reassembled
889
        if (packageTarBall)
890
        {
891
            fullyPublished = assemblePackage();
892
        }
893
 
894
        if (fullyPublished)
895
        {
896
            if ( generic )
897
            {
898
                //  Generic - only one marker file
899
                fullyPublished = checkPublished( dpkgArchive, "generic" );
900
            }
901
            else
902
            {
903
                //  Multi machine package
904
                //  Scan required target machines artifacts
905
                //  Expand from MachType to one or more MachName's
906
                scanBuilds:
907
                    for (Iterator<BuildInfo> ip=buildInfoCollection.iterator(); ip.hasNext(); )
908
                    {
909
                        BuildInfo buildInfo = ip.next();
910
                        for (Iterator<Machine> it=abtData.machineCollection.iterator(); it.hasNext(); )
911
                        {
912
                            Machine ma = it.next();
913
                            if (ma.getMachtype().compareTo(buildInfo.getMachtype()) == 0 )
914
                            {
915
                                fullyPublished = checkPublished( dpkgArchive, ma.getName() );
916
                                if ( !fullyPublished )
917
                                {
918
                                    //  Break out of both loops
919
                                    //  Once we have seen an error we need to retain it.
920
                                    break scanBuilds;
921
                                }
922
                            }
923
                        }
924
                    }
925
            }
926
        }
927
 
928
        //  Detect problem with zero length descpkg file
929
        //      May be caused by write clash from multiple machines
930
        //      Don't know
931
        //
932
        //  Not forcing NFS flush as this will have been done in the previous step
933
        //
934
        if ( fullyPublished )
935
        {
936
            String destination = utilities.catDir(dpkgArchive, packageName, packageFullVersion, "descpkg");
937
            File flag = new File( destination);
938
 
939
            //  File Must
940
            //      Exist
941
            //      Be a File
942
            //      Have a length. Problem appears to be zero length file
943
            //
944
            boolean found = false;
945
            logMsg( "published. Descpkg Sanity Test: " + flag.getPath(), DEBUG );
946
            if (!flag.exists() ) {
947
                reportErrorException( "No descpkg file. Package may not build with current build filters", 261 );
948
 
949
            } else if ( !flag.isFile()) {
950
                reportErrorException( "Descpkg Sanity Test: Is not a file", 261 );
951
 
952
            } else if ( flag.length() <= 0 ) {
953
                reportErrorException( "Descpkg Sanity Test: Zero length File", 261 );
954
 
955
            } else {
956
                logMsg( "published. Descpkg Sanity Test: Passed", INFO );
957
                found = true;
958
            }
959
 
960
            if (!found) {
961
                fullyPublished = false;
962
            }
963
        }
964
 
965
        if ( fullyPublished && daemon != null )
966
        {
967
            if ( doesNotRequireSourceControlInteraction == null )
968
            {
969
                //
970
                //  Save modified build files
971
                //  Label the resultant files
972
                //  Create a command of the form:
973
                //      jats etool jats_vcssave_build
974
                //          -infile     auto.xml/auto.pl
975
                //          -outfile    xxxdepends.xml/build.pl
976
                //          -pname      package_name
977
                //          -pversion   package_version
978
                //          -infofile   path_to_info_file
979
                //          -wiplabel   Existing WIP label (optional)
980
                //          -baselabel  View label
981
 
982
                logMsg("publish save build files", WARN);
983
 
984
                File saveinfo = new File(utilities.catDir(basedir, rtagId + "abtinfo.txt"));
985
                if ( saveinfo.exists() )
986
                {
987
                    saveinfo.delete();
988
                }
989
 
990
                command.init("jats" );
991
                addCommandLocate();
992
                command.add( "etool", "jats_vcssave_build" );
993
 
994
                if ( packageStandard == BuildStandards.ANT )
995
                {
996
                    command.add( "-infile", "auto.xml" );
997
                    command.add( "-outfile", packageName + "depends.xml" );
998
                }
999
                else
1000
                {
1001
                    command.add( "-infile", "auto.pl" );
1002
                    command.add( "-outfile", "build.pl" );
1003
                }
1004
 
1005
                command.add( "-pname", packageName );
1006
                command.add( "-pversion", packageFullVersion );
1007
                command.add( directChange != null, "-isawip" );
1008
                command.add( "-infofile", saveinfo.getAbsolutePath() );
1009
                command.add( "-baselabel", packageVcsTag );
1010
 
1011
                if ( oldExtension != null && newExtension != null && packageExtension.compareTo( newExtension ) == 0 )
1012
                {
1013
                    // only branch build.pl where its extension is being migrated
1014
                    command.add( "-branch", "project_migration_branch", "-newbranch" );
1015
                }
1016
 
1017
                runCommand( "Failure to save build file changes into source control" );
1018
 
1019
                //
1020
                //  The command creates an info file(saveinfo) to pass information back
1021
                //  to the caller (me). This is a 'properties' file
1022
                //  Need to extract the following information
1023
                //    newVcsTag - which is held as VCS.tag
1024
                //
1025
                logMsg("publish read info file", INFO);
1026
 
1027
                Properties properties = new Properties();
1028
                try
1029
                {
1030
                    properties.load(new FileInputStream(saveinfo));
1031
                }
1032
                catch (IOException e)
1033
                {
1034
                    reportErrorException( "Failed to open save_build info file", 262 );
1035
                }
1036
 
1037
                newVcsTag = properties.getProperty("VCS.tag" );
1038
                if ( newVcsTag == null )
1039
                {
1040
                    reportErrorException( "Save_build info. Missing property:VCS.tag", 262 );
1041
                }
1042
                logMsg("publish read info file. Label:" + newVcsTag , INFO);
1043
            }
1044
        }
1045
    }
1046
 
1047
    /** Re-assemble package fragments into a package within the target archive
1048
     *  Used only in non-escrow mode
1049
     *  
1050
     *  This method will invoke a command on the target package server
1051
     *  This is done to overcome several issues:
1052
     *  1) Atomic merging of package fragments
1053
     *  2) Very long times seen in transferring a package with a large number of files
1054
     *     over a non-local network. It may take a second to create a file. For a 3000 file
1055
     *     package we were seeing times of about an hour simply to transfer the files from AWS(Sydney)
1056
     *     to the package server in Perth.
1057
     *     
1058
     *  The down side is that we need to set up an SSH session to the package server
1059
     *  We need:
1060
     *  1) Network name of the machine
1061
     *  2) User on the machine to do the work
1062
     *  3) Credentials for that user
1063
     *  
1064
     *   The existence of these items will have been performed by the daemon at startup
1065
     *   This simplifies the process of reporting errors
1066
     * 
1067
     * @return  true - reassemble occurred correctly
1068
     * @throws Exception 
1069
     */
1070
    private boolean assemblePackage() throws Exception 
1071
    {
1072
        if ( daemon == null )
1073
        {
1074
            // Not to be used in escrow
1075
            return false;
1076
        }
1077
        /*
1078
         *  Setup the credentials
1079
         *  The format 'should' have been checked as the daemon started
1080
         *  The link should have been authenticated before the build was started,
1081
         *  but it may have gone down since.
1082
         */
1083
        LogOutput logger = new LogOutput()
1084
        {
1085
            @Override
1086
            public void data(String message) {
1087
                logMsg( message, INFO );
1088
            }
1089
 
1090
            @Override
1091
            public void info(String message) {
1092
                logMsg( message, INFO );
1093
            }
1094
 
1095
            @Override
1096
            public void fatal(String message) {
1097
                logMsg( message, FATAL);
1098
            }
1099
        };
1100
 
1101
        ElapseTime et = new ElapseTime();
1102
        RemoteExecution mRemoteExecution = new RemoteExecution(logger);
1103
 
1104
        /*
1105
         * Generate the command string
1106
         * Its being executed over an ssh session so we need to:
1107
         *  1) Set up the required environment
1108
         *  2) Set the location of GBE_DPKG - more for testing
1109
         */
1110
        command.init();
1111
        command.add("sudo","-n", "-u", "buildadm", "/home/releasem/sbin/jatsTool", "assemble_dpkg");
1112
        command.add(useTestArchive, "-testArchive");
1113
        command.add("'-pname=" + packageName + "'");
1114
        command.add("'-pversion=" + packageFullVersion + "'");
1115
 
1116
        String cmd = command.toString();
1117
        logMsg( "assemblePackage. Command:" + cmd, WARN );
1118
        int retCode = mRemoteExecution.execute(cmd);
1119
        logMsg( "command returned: "+ retCode + ", elapsed time (S): " + et.toString(), WARN);
1120
        if (retCode != 0)
1121
        {
1122
            reportErrorException( "Package reassembly error", 267 );
1123
        }
1124
        return 0 == retCode;
1125
    }
1126
 
1127
    /** determineBuildStandard
1128
     *  Process the current target and set up
1129
     *      buildStandard
1130
     *          compileTarget
1131
     *          javaVersion
1132
     *          
1133
     *      packageStandard
1134
     *          The package standard is used to determine the mode used to process the auto.cfg file
1135
     *          
1136
     */
1137
    private void determineBuildStandard() throws Exception 
1138
    {
1139
        // Scan the platform collection looking for an entry that matches the current machine
1140
        //
1141
        // Just wanting to set up
1142
        //    buildStandard and one of
1143
        //        compileTarget
1144
        //    OR  javaVersion
1145
 
1146
        for (Iterator<BuildInfo> it = buildInfoCollection.iterator(); it.hasNext();)
1147
        {
1148
            BuildInfo buildInfo = it.next();
1149
            String method = buildInfo.getMethod();
1150
            String arg = buildInfo.getArg();            
1151
 
1152
            //  Capture the first non-null build standard as the packageStandard
1153
            if ( packageStandard == BuildStandards.NONE)
1154
            {
1155
                if (method.equals("jats"))
1156
                {
1157
                    packageStandard = BuildStandards.JATS;
1158
                }
1159
                else if (method.equals("ant"))
1160
                {
1161
                    packageStandard = BuildStandards.ANT;
1162
                }
1163
            }
1164
 
1165
            //  Capture the build standard for the current machine type
1166
            if (gbeMachtype.compareTo(buildInfo.getMachtype()) == 0)
1167
            {
1168
                if (method.equals("jats"))
1169
                {
1170
                    buildStandard = BuildStandards.JATS;
1171
                    if (arg.compareTo("production") == 0)
1172
                    {
1173
                        compileTarget = CompileTargets.PROD;
1174
 
1175
                    }
1176
                    else if (arg.compareTo("debug") == 0)
1177
                    {
1178
                        compileTarget = CompileTargets.DEBUG;
1179
 
1180
                    }
1181
                    else if (arg.compareTo("all") == 0)
1182
                    {
1183
                        compileTarget = CompileTargets.ALL;
1184
 
1185
                    }
1186
                    else
1187
                    {
1188
                        reportErrorException("Failure, unsupported Jats build environment " + arg + ", internal ABT problem", 256);
1189
                    }   
1190
                }
1191
                else if (method.equals("ant"))
1192
                {
1193
                    buildStandard = BuildStandards.ANT;
1194
 
1195
                    //    Handle version of 'none' and of the form 'n.n'
1196
                    //    Anything else is an error
1197
 
1198
                    javaVersion = new JavaVersions(arg);
1199
                    if ( javaVersion.isBad())
1200
                    {
1201
                        reportErrorException("Failure, unsupported Ant build environment " + arg + ", internal ABT problem", 256);
1202
                    }
1203
                }
1204
 
1205
                else if (method.equals("none"))
1206
                {
1207
                    buildStandard = BuildStandards.NONE;
1208
                }
1209
                else
1210
                {
1211
                    reportErrorException("Failure, unsupported build method " + method + ", internal ABT problem", 256);    
1212
                }
1213
            }
1214
        }
1215
 
1216
        //
1217
        //    Log the build method and arguments
1218
        //
1219
        logMsg("execute packageStandard: ", packageStandard.getBuildStandard());
1220
        logMsg("execute buildStandard: ", buildStandard.getBuildStandard());
1221
        if (buildStandard == BuildStandards.ANT )
1222
        {
1223
            logMsg("execute javaVersion: ", javaVersion.getJavaVersion());    
1224
        }
1225
        else if (buildStandard == BuildStandards.JATS )
1226
        {
1227
            logMsg("execute compileTarget: ", compileTarget.getCompileTarget());    
1228
        }
1229
 
1230
 
1231
        //  Daemon Mode Only
1232
        //  If we have an ANT Build then we may have an additional problem.
1233
        //  If there is more than one machine of the same 'Machine Class' in the buildset, then
1234
        //  we need to limit the build to just one of them.
1235
        //  In Escrow this is not an issue as the builds are done serially
1236
        //
1237
        //  The rule is:
1238
        //    If there is only one machine in the class - then use it
1239
        //    If there are multiple machines of the same class - then use the first one that has JAVA in its build filter
1240
        //    If none have JAVA in the build filter, then use the first one in the list
1241
        // Supplementary Rules:
1242
        //    If a machine does no have a buildfilter, then assume that it can build everything
1243
        // 
1244
        // Rule Simplification:
1245
        //    If this machine is building ANT, then exclude ourself from the build if
1246
        //    another machine satisfies the criteria. ie: another machine will determine that
1247
        //    it will build the ANT component.
1248
        //
1249
        if (buildStandard == BuildStandards.ANT && daemon != null)
1250
        {
1251
            int classCount = 0;
1252
            Machine firstWithJava = null;
1253
            Machine firstInMachClass = null;
1254
 
1255
            for (Iterator<Machine> it = abtData.machineCollection.iterator(); it.hasNext();)
1256
            {
1257
                Machine ma = it.next();
1258
                if (ma.getMachclass().equals(mMachine.getMachclass()) )
1259
                {
1260
                    classCount++;
1261
 
1262
                    if (firstInMachClass == null)
1263
                        firstInMachClass = ma;
1264
 
1265
                    if (firstWithJava == null)
1266
                    {
1267
                        String buildFilter = ma.getBuildfilter();
1268
                        if (buildFilter != null)
1269
                        {
1270
                            buildFilter = "," + buildFilter.replace(" ", ",") + ",";
1271
                        }
1272
 
1273
                        if (buildFilter == null || buildFilter.contains(",JAVA,"))
1274
                        {
1275
                            firstWithJava = ma;
1276
                        }
1277
                    }
1278
                }
1279
            }
1280
 
1281
            // If none have 'JAVA', then used the first machine in the nominated class
1282
            if (firstWithJava == null)
1283
            {
1284
                firstWithJava = firstInMachClass;
1285
            }
1286
 
1287
 
1288
            //
1289
            //  Apply the rule described above.
1290
            //  Really only need to disqualify ourselves iff there is another machine that will do the build
1291
            //
1292
            if ((classCount > 1) && (firstWithJava != null) && (mMachine != firstWithJava))
1293
            {
1294
                javaVersion = JavaVersions.SKIP;
1295
                logMsg("execute determineBuildStandard: Exclude myself from ANT Build", INFO);
1296
            }
1297
        }
1298
    }
1299
 
1300
 
1301
    /** execute
1302
     *  The Ant Task entry point. This is invoked to perform the targets action
1303
     *      Display the start and end time of the action
1304
     */
1305
    @Override
1306
    public void execute()
1307
    {
1308
        ElapseTime et = new ElapseTime();
1309
 
1310
        //  Setup enough information to enable logging
1311
        project = getProject();
1312
        target = getOwningTarget();
1313
        daemon = project.getProperty("abt_daemon");
1314
        rtagId = project.getProperty("abt_rtag_id");
1315
        release = project.getProperty("abt_release");
1316
 
1317
        logMsg( "execute start: " + ElapseTime.getTimeStamp(), WARN );
1318
        if ( daemon != null ) {
1319
            logMsg("execute daemon: yes", INFO);
1320
        }
1321
 
1322
        try {
1323
            executeAbtTask();    
1324
        }
1325
        finally         {
1326
            logMsg( "execute complete: " + ElapseTime.getTimeStamp(), INFO );
1327
            logMsg( "execute elapsed time (S): " + et.toString(), WARN);
1328
        }
1329
    }
1330
 
1331
    /** executeAbtTask
1332
     *  Body of the ABT execution task
1333
     *  Factored out so that a time stamp can be added to the log
1334
     */
1335
    private void executeAbtTask()
1336
    {
1337
        boolean errorReported = false;
1338
        boolean benign = false;
1339
        boolean skipped = false;
1340
 
1341
        try
1342
        {
1343
            // required by the Execute API on non win32 platforms, don't ask because I don't know
1344
            project.setProperty("ant.home", System.getenv("ANT_HOME"));
1345
 
1346
            // Setup the base name of the output log file
1347
            // Need to do before we report errors
1348
            if ( daemon != null )
1349
            {
1350
                //  Use the packages name and version
1351
                packageName = project.getProperty("abt_package_name");
1352
                logMsg("execute packageName: ", packageName);
1353
 
1354
                packageFullVersion = project.getProperty("abt_package_version");
1355
                logMsg("execute packageFullVersion: ", packageFullVersion);
1356
 
1357
                logBase = packageName + "_" +  packageFullVersion;
1358
            }
1359
            else
1360
            {
1361
                // Use the current target - which will be the packages name and version
1362
                logBase = target.getName();
1363
            }
1364
 
1365
            // Check the current hostname
1366
            //    Needed early as its used in error reporting
1367
            //    JATS should ensure that this value is set
1368
            // Daemon Mode:
1369
            //    When sending emails
1370
            //    Identify the target machine parameters
1371
            // Escrow Mode:
1372
            //    Determine escrow build components
1373
            //    
1374
            if (hostname == null) {
1375
                hostname = "unknown";
1376
                reportErrorException( "GBE_HOSTNAME environment variable not set", 256 );
1377
            }
1378
 
1379
            // early target related
1380
            packageAlias = target.getName();
1381
            packageVcsTag = project.getProperty(packageAlias + "packagevcstag");
1382
            logMsg("execute packageVcsTag: ", packageVcsTag);
1383
 
1384
            if ( packageVcsTag == null )
1385
            {
1386
                // this abt task has no properties, by design
1387
                // future use to estimate build completion time
1388
                logMsg("execute packageAlias: " + packageAlias, INFO);
1389
                return;
1390
            }
1391
 
1392
            logMsg("execute packageAlias: " + packageAlias, WARN);
1393
 
1394
            // ant built in
1395
            basedir = project.getProperty("basedir");
1396
            logMsg("execute basedir: ", basedir);
1397
 
1398
            // global
1399
 
1400
            if ( gbeMachtype == null ) {
1401
                reportErrorException( "GBE_MACHTYPE environment variable not set", 256 );
1402
            }
1403
 
1404
            if (dpkgArchive == null) {
1405
                reportErrorException( "GBE_DPKG environment variable not set", 256 );
1406
            }
1407
 
1408
            //  Locate ABTDATA
1409
            //  This will be referenced by a known ID
1410
            abtData = (ABTData) project.getReference("global-abt-data");
1411
            if (abtData == null) {
1412
                reportErrorException( "ABTData Task not found", 256 );
1413
            }
1414
 
1415
            if ( daemon != null )
1416
            {
1417
 
1418
                mailServer = project.getProperty("abt_mail_server");
1419
                if ( mailServer == null )
1420
                {
1421
                    reportErrorException( "Missing ANT property: abt_mail_server", 256 );
1422
                }
1423
                logMsg("execute mailServer: ", mailServer);
1424
 
1425
                mailSender = project.getProperty( "abt_mail_sender" );
1426
                if ( mailSender == null )
1427
                {
1428
                    reportErrorException( "Missing ANT property: abt_mail_sender", 256 );
1429
                }
1430
                logMsg("execute mailSender: ", mailSender);
1431
 
1432
                for (Iterator<Owner> it=abtData.ownerCollection.iterator(); it.hasNext(); )
1433
                {
1434
                    Owner owner = it.next();
1435
 
1436
                    if ( owners.length() > 0 )
1437
                    {
1438
                        owners.append(",");
1439
                    }
1440
                    owners.append(owner.getEmail());
1441
                    logMsg("execute owner: ", owner.getEmail());
1442
                }
1443
                logMsg("execute owners: ", owners.toString());
1444
            }
1445
 
1446
            if ( daemon == null)
1447
            {
1448
                // Locate any entry for my machType and use it to convert into machClass
1449
                // In escrow the hostName cannot be used.
1450
                //    
1451
                for (Iterator<Machine> it=abtData.machineCollection.iterator(); it.hasNext(); )
1452
                {
1453
                    Machine ma = it.next();
1454
                    if (ma.getMachtype().compareTo(gbeMachtype) == 0 )
1455
                    {
1456
                        gbeMachClass = ma.getMachclass();
1457
                        break;
1458
                    }
1459
                }
1460
 
1461
                if (gbeMachClass == null)
1462
                {
1463
                    reportErrorException( "No MachClass mapping for " + gbeMachtype, 256 );
1464
                }
1465
                logMsg("execute gbeMachClass: ", gbeMachClass);
1466
            }
1467
 
1468
            // project related
1469
            // Some data has already been collected. Just log it.
1470
            logMsg("execute rtagId: ", rtagId);
1471
            logMsg("execute release: ", release);
1472
 
1473
            packageVersionID = project.getProperty("abt_package_version_id");
1474
            if (packageVersionID != null)
1475
            {
1476
                logMsg("execute packageVersionID: ", packageVersionID); 
1477
            }
1478
 
1479
            buildtoolVersion = project.getProperty("abt_buildtool_version");
1480
            logMsg("execute buildtoolVersion: ", buildtoolVersion);
1481
 
1482
            family = project.getProperty("abt_family");
1483
            logMsg("execute family: ", family);
1484
 
1485
            oldExtension = project.getProperty("abt_old_extension");
1486
            logMsg("execute oldExtension: ", oldExtension);
1487
 
1488
            newExtension = project.getProperty("abt_new_extension");
1489
            logMsg("execute newExtension: ", newExtension);
1490
 
1491
            {
1492
                 String prop = project.getProperty("abt_test_build_instruction");
1493
                 logMsg("execute testBuildInstruction: ", prop);
1494
                 testBuildInstruction = 0;
1495
                 if ( prop != null)
1496
                 {
1497
                     testBuildInstruction = Integer.parseInt(prop);
1498
                 }
1499
            }
1500
 
1501
            {
1502
                String prop = project.getProperty("abt_is_ripple");
1503
                logMsg("execute isRipple: ", prop);
1504
                isaRipple = ( prop != null && Integer.parseInt(prop) > 0);
1505
            }
1506
 
1507
 
1508
            if ( project.getProperty("abt_packagetarball") != null ) {
1509
                packageTarBall = true;
1510
                logMsg("execute packageTarBall: yes", INFO);  
1511
            }
1512
 
1513
            if ( project.getProperty("abt_usetestarchive") != null ) {
1514
                useTestArchive = true;
1515
                logMsg("execute useTestArchive: yes", INFO);  
1516
            }
1517
 
1518
            // Locate Machine Information for this machine
1519
            //    It contains the build filter for the current machine
1520
            //    Only present in daemon builds
1521
            //
1522
            for (Iterator<Machine> it=abtData.machineCollection.iterator(); it.hasNext(); )
1523
            {
1524
                Machine ma = it.next();
1525
                if (ma.getName().compareTo(hostname) == 0 )
1526
                {
1527
                    mMachine = ma;
1528
                    logMsg("execute machine: ", mMachine.getName() + ", Type:" + mMachine.getMachtype() + ", Class:" + mMachine.getMachclass() + ", Master:" + mMachine.getMaster() ); 
1529
                    break;
1530
                }
1531
            }
1532
 
1533
            if ( (daemon != null) && (mMachine == null) ) {
1534
                reportErrorException( "Cannot find Machine entry for: " + hostname, 256 );
1535
            }
1536
 
1537
            //  Setup machine specific information
1538
            //    Build Filter
1539
            //    Master Mode
1540
            if (mMachine != null) 
1541
            {
1542
                if (mMachine.getMaster() != null)
1543
                {
1544
                    master = true;
1545
                    logMsg("execute master: ", "true");
1546
                }
1547
 
1548
                gbebuildfilter = mMachine.getBuildfilter(); 
1549
                if ( gbebuildfilter != null )
1550
                {
1551
                    //
1552
                    // Ensure the Execute task passes gbebuildfilter as one parameter...
1553
                    // Replace spaces with commas
1554
                    //
1555
                    gbebuildfilter = gbebuildfilter.replace( " ", ",");
1556
                    logMsg("execute gbebuildfilter: ", gbebuildfilter);
1557
                }
1558
            }
1559
 
1560
            // Extract the build standard information from the abt element
1561
            //  Sets up buildStandard and one of
1562
            //            compileTarget
1563
            //        OR  javaVersion
1564
 
1565
            determineBuildStandard();
1566
            if ( buildStandard == BuildStandards.NONE)
1567
            {
1568
                //  Flag a benign build is good
1569
                //  A benign is a no-operation. The build is not required on the current machine
1570
                //
1571
                benign = true;
1572
            }
1573
 
1574
            if ( buildStandard == BuildStandards.ANT && javaVersion == JavaVersions.SKIP )
1575
            {
1576
                //  Flag a benign build - we are not building
1577
                //  Flag a skipped build - we need to place a marker in dpkg_archive
1578
                // 
1579
                //  JavaVersions.SKIP is used when a ANT build could be done on multiple machines
1580
                //  It must only be done on one such machine
1581
                // 
1582
                benign = true;
1583
                skipped = true;
1584
            }
1585
 
1586
            // Do we really need to extract and work with the source
1587
            //      Escrow Mode : yes (Not done here)
1588
            //      Daemon Mode :
1589
            //          If Master : Yes. We need to generate metrics and update the build file
1590
            //          Not Master: May be
1591
            //                      If a benign build : No
1592
            boolean extractSource = true;
1593
            if ( daemon != null && !master && benign ) {
1594
                extractSource = false;
1595
            }
1596
            logMsg("execute extractSource: ", Boolean.toString(extractSource));
1597
            logMsg("execute benign: ", Boolean.toString(benign));
1598
            logMsg("execute skipped: ", Boolean.toString(skipped));
1599
 
1600
            // redirect all thread (therefore jats) output to the output file in the basedir
1601
            re = new Redirector(this);
1602
            if ( daemon != null )
1603
            {
1604
                // thread logging is done to <rtagId>thread.log and is continually re-used every build
1605
                // full thread and non thread (ie abt logging) is done to the DefaultLogger set up by the build daemons, <rtagId>.log
1606
                // this file is copied on a build failure to cwd (if it exists) and is continually re-used every build
1607
 
1608
                // capture full logging
1609
                re.setAlwaysLog(true);
1610
            }
1611
            else
1612
            {
1613
                output = new File( logBase + ".log" );
1614
            }
1615
 
1616
            if (output != null)
1617
            {
1618
                re.setOutput( output );
1619
            }
1620
            thread = new Execute(re.createHandler());
1621
            thread.setAntRun( project );
1622
            thread.setVMLauncher(false);
1623
 
1624
            // must set up package name and owners before reportError
1625
            packageName = project.getProperty(packageAlias + "packagename");
1626
            logMsg("execute packageName: ", packageName);
1627
 
1628
            //-----------------------------------------------------------------------
1629
            //    AbtTestPath
1630
            //
1631
            if ( packageAlias.compareTo("AbtTestPath") == 0 )
1632
            {
1633
 
1634
                // jats -label check pkgVcsTag
1635
                command.init("jats", "label","-check" );
1636
                command.add( packageVcsTag );
1637
                //command.add( "-verbose=2" );
1638
 
1639
                runCommand( "Failure to validate label in source control" );
1640
 
1641
                return;
1642
            }
1643
 
1644
            //-----------------------------------------------------------------------
1645
            //    AbtSetUp
1646
            //
1647
            if ( packageAlias.compareTo("AbtSetUp") == 0 )
1648
            {
1649
                // create rtag_id directory from scratch
1650
                File rId = new File( rtagId );
1651
                deleteDirectory(rId);
1652
                if (rId.exists())
1653
                {
1654
                    reportErrorException( "Build directory not empty", 264 );
1655
                }
1656
                rId.mkdirs();
1657
 
1658
                if (extractSource)
1659
                {
1660
                    // jats jats_vcsrelease -extract -label=pkgVcsTag -path=src_path -root=rtag_id/timestamp -tag=timestamp -noprefix
1661
                    command.init("jats", "jats_vcsrelease","-extract" );
1662
                    command.add( "-label=" + packageVcsTag );
1663
                    command.add( "-root=" + rtagId );
1664
                    command.add( "-tag=" + daemon );
1665
                    command.add( "-noprefix" );
1666
                    command.add(!master, "-extractfiles");
1667
                    //command.add( "-verbose=2" );
1668
 
1669
                    runCommand( "Failure to extract source code from source control" );
1670
                }
1671
                return;
1672
            }
1673
 
1674
            //-----------------------------------------------------------------------
1675
            //    AbtTearDown
1676
            //
1677
            if ( packageAlias.compareTo("AbtTearDown") == 0 )
1678
            {
1679
                // tear the build view down, regardless of build error
1680
                wd = new File( basedir );
1681
 
1682
                // only now change the thread working directory back
1683
                thread.setWorkingDirectory( wd );
1684
 
1685
                File buildDirectory = new File(wd + getProject().getProperty("abt_package_location"));
1686
 
1687
                if ( buildDirectory.exists() )
1688
                {
1689
                    // jats jats_vcsrelease -label pkgTag -root=rtag_id/timestamp -tag=timestamp -noprefix -delete=2
1690
                    command.init("jats", "jats_vcsrelease" );
1691
                    command.add( "-label=" + packageVcsTag );
1692
                    command.add( "-root=" + rtagId );
1693
                    command.add( "-tag=" + daemon );
1694
                    command.add( "-noprefix" );
1695
                    command.add( "-delete=2" );
1696
                    //command.add( "-verbose=2" );
1697
 
1698
                    runCommand( "Failure to remove source code extraction" );
1699
                }
1700
 
1701
                //  delete the rtagId directory
1702
                //  If it cannot be deleted then the build has done something ugly
1703
                //  Left over bits will only hurt following builds
1704
                File rId = new File( rtagId );
1705
                deleteDirectory(rId);
1706
                if (rId.exists() )
1707
                {
1708
                    reportErrorException( "Build directory cannot be removed after build", 264 );
1709
                }
1710
 
1711
                // Always save the log files
1712
                saveLogs();
1713
 
1714
                return;      
1715
            }
1716
 
1717
            // target related    
1718
            packageVersion = project.getProperty(packageAlias + "packageversion");
1719
            logMsg("execute packageVersion: ", packageVersion);
1720
 
1721
            packageExtension = project.getProperty(packageAlias + "packageextension");
1722
            logMsg("execute packageExtension: ", packageExtension);
1723
 
1724
            packageFullVersion = packageVersion + packageExtension;
1725
            logMsg("execute packageFullVersion: ", packageFullVersion);
1726
 
1727
            packageLoc = packageName + packageExtension;
1728
            logMsg("execute packageLoc: ", packageLoc);
1729
 
1730
            if ( project.getProperty(packageAlias + "generic") != null ) {
1731
                generic = true;
1732
                logMsg("execute generic: yes", INFO);  
1733
            }
1734
 
1735
            directChange = project.getProperty(packageAlias + "directchange");
1736
            if ( directChange != null )
1737
            {
1738
                logMsg("execute directChange: yes", INFO);  
1739
            }
1740
 
1741
            doesNotRequireSourceControlInteraction = project.getProperty(packageAlias + "doesnotrequiresourcecontrolinteraction");
1742
            if ( doesNotRequireSourceControlInteraction != null )
1743
            {
1744
                logMsg("execute doesNotRequireSourceControlInteraction: true", INFO);  
1745
            }
1746
 
1747
            //    Display details of the BuildInfo Jats and Ant elements within the
1748
            //    current ABT element
1749
            //
1750
            for (Iterator<BuildInfo> it=buildInfoCollection.iterator(); it.hasNext(); )
1751
            {
1752
                BuildInfo buildInfo = it.next();
1753
                logMsg("execute buildinfo: ", "MachType: " +  buildInfo.getMachtype() + " Method: " + buildInfo.getMethod() + " " + buildInfo.getArg() );
1754
            }
1755
 
1756
 
1757
            // Set newVsTag to the existing VcsTag
1758
            // Will be used when rebuilding a package that already exists
1759
            newVcsTag = packageVcsTag;
1760
 
1761
            //
1762
            //    Determine the location of the package, relative to 'basedir'
1763
            //    Change to this directory for the remainder of the build processing
1764
            loc = project.getProperty(packageAlias + "loc");
1765
            logMsg("execute loc: ", loc);
1766
 
1767
            cwd = utilities.catDir(basedir, loc);
1768
            logMsg("execute cwd: ", cwd);
1769
 
1770
            wd = new File( cwd );
1771
            if ( !wd.exists() )
1772
            {
1773
                reportErrorException( "Failure " + cwd + " does not exist", 265 );
1774
            }
1775
 
1776
            // only now change the thread working directory
1777
            thread.setWorkingDirectory( wd );
1778
 
1779
            //-----------------------------------------------------------------------
1780
            //    AbtPublish
1781
            //    Note: Have changed directory to the working directory
1782
            //
1783
            if ( packageAlias.compareTo("AbtPublish") == 0 )
1784
            {
1785
                puplishPackage();
1786
                if ( daemon != null )
1787
                {
1788
                    // set properties to drive BuildThread attributes
1789
                    // these are used to determine what ant did
1790
                    getProject().setProperty("abt_fully_published", Boolean.toString(fullyPublished));
1791
                    getProject().setProperty("abt_new_vcstag", newVcsTag);
1792
                }
1793
 
1794
                return;
1795
            }
1796
 
1797
            //-----------------------------------------------------------------------
1798
            //    Build Target
1799
            //    Note: Have changed directory to the working directory
1800
            //
1801
            packageVersionID = project.getProperty(packageAlias + "pv_id");
1802
            logMsg("execute packageVersionID: ", packageVersionID);
1803
 
1804
            unittests = project.getProperty(packageAlias + "unittests");
1805
            if ( unittests != null )
1806
            {
1807
                logMsg("execute unittests: yes", INFO);
1808
            }
1809
 
1810
            for (Iterator<Depend> it=dependCollection.iterator(); it.hasNext(); )
1811
            {
1812
                Depend depend = it.next();
1813
                logMsg("execute depend: ", depend.getPackage_Alias());
1814
            }
1815
 
1816
            if ( daemon == null )
1817
            {
1818
                // Escrow Only
1819
                // Recognize an escrow will be run multiple times on a build stage
1820
                //      Do not force continuous rebuilding each time
1821
                //      Has this package version already been published on this platform
1822
                if ( checkEscrowMarker() )
1823
                {
1824
                    logMsg( "execute package has been published on this platform - skipping", INFO);
1825
                    propertyValue = "257";
1826
                    throw new Exception();
1827
                }
1828
            }
1829
            else
1830
            {
1831
                // DEVI 56714 daemon centric check
1832
                String majorV = this.getClass().getPackage().getSpecificationVersion();
1833
 
1834
                if ( buildtoolVersion.compareTo( majorV ) != 0 )
1835
                {
1836
                    reportErrorException( "Failure, incompatible build.xml not generated with version " + majorV, 256 );
1837
                }
1838
            }
1839
 
1840
 
1841
            if (extractSource)
1842
            {
1843
                //  Init the metrics gathering process
1844
                metricsBegin();
1845
 
1846
                //  Generate auto.pl or <PackageName>depends.xml file
1847
                genbuild();
1848
 
1849
                //  Active build
1850
                //      Build the target package unless we are simply doing metrics generation
1851
                //
1852
                if ( !benign )
1853
                {
1854
                    jatsBuildPackage();
1855
                }
1856
 
1857
                //  Complete the metrics gathering
1858
                metricsEnd();
1859
            }
1860
 
1861
            //
1862
            //  Process Skipped builds
1863
            //    Create a built.xxx marker for the publish check
1864
            //
1865
            if (skipped)
1866
            {
1867
                jatsSkipPackage();
1868
            }
1869
 
1870
        }
1871
        catch( SecurityException e)
1872
        {
1873
            errorReported = true;
1874
            reportError( "Failure caught SecurityException", 256 );
1875
        }
1876
        catch( IOException e)
1877
        {
1878
            errorReported = true;
1879
            reportError( "Failure caught IOException", 256 );
1880
        }
1881
        catch( Exception e)
1882
        {
1883
            // assume this condition has been reported on
1884
            errorReported = true;
1885
 
1886
            if ( e.getMessage() != null )
1887
            {
1888
                logMsg( "execute caught Exception " + e.getMessage(), WARN );
1889
            }
1890
            else
1891
            {
1892
                logMsg( "execute caught Exception", WARN );
1893
            }
1894
        }
1895
        finally
1896
        {
1897
            try
1898
            {
1899
                if ( daemon != null )
1900
                {
1901
                    // do not write to publish.log
1902
                    throw new IOException();
1903
                }
1904
 
1905
                FileWriter publish = new FileWriter( utilities.catDir(basedir,"publish.log"), true );
1906
                if ( propertyValue.compareTo( "0" ) == 0 )
1907
                {
1908
                    if ( benign )
1909
                    {
1910
                        publish.write( "successfully published " + packageName + " at " + packageFullVersion + ", no action required on this platform" );
1911
                    }
1912
                    else
1913
                    {
1914
                        publish.write( "successfully published " + packageName + " at " + packageFullVersion );
1915
                    }
1916
 
1917
                    publish.write( ls );
1918
                }
1919
                else if ( propertyValue.compareTo( "256" ) == 0 )
1920
                {
1921
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion +  ", internal abt issue" + ls );
1922
                }
1923
                else if ( propertyValue.compareTo( "257" ) == 0 )
1924
                {
1925
                    errorReported = false;
1926
                    publish.write( "previously published " + packageName + " at " + packageFullVersion + ls );
1927
                }
1928
                else if ( propertyValue.compareTo( "261" ) == 0 )
1929
                {
1930
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", missing or bad descpkg file" + ls );
1931
                }
1932
                else if ( propertyValue.compareTo( "262" ) == 0 )
1933
                {
1934
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", couldn't process save_build info" + ls );
1935
                }
1936
                else if ( propertyValue.compareTo( "263" ) == 0 )
1937
                {
1938
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", couldn't write to auto.cfg" + ls );
1939
                }
1940
                else if ( propertyValue.compareTo( "265" ) == 0 )
1941
                {
1942
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", " + cwd + " does not exist" + ls );
1943
                }
1944
                else if ( propertyValue.compareTo( "264" ) == 0 )
1945
                {
1946
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", " + " Could not delete build directory" + ls );
1947
                }
1948
                else if ( propertyValue.compareTo( "267" ) == 0 )
1949
                {
1950
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", " + " Could not assemble package fragments" + ls );
1951
                }
1952
                else
1953
                {
1954
                    // nb jats or ant can presumably return a value 1 to 255
1955
                    publish.write( "failed to publish " + packageName + " at " + packageFullVersion + ", jats or ant failed" + ls );
1956
                }
1957
 
1958
                publish.close();
1959
            }
1960
            catch( IOException e )
1961
            {
1962
                if ( daemon == null )
1963
                {
1964
                    reportError( "Failure to write to publish.log", 266 );
1965
                }
1966
            }
1967
            catch( Exception e )
1968
            {
1969
                if ( daemon == null )
1970
                {
1971
                    reportError( "Failure to write to publish.log", 266 );
1972
                }
1973
            }
1974
 
1975
            getProject().setProperty(packageAlias + ".res", propertyValue);
1976
 
1977
            if ( errorReported )
1978
            {
1979
                // designed to prevent subsequent build activity on this build file
1980
                // supply the build failure log file in message with / as file sep
1981
                // takes the form hostname/rtag_id/daemon/logfile
1982
                if ( daemon != null )
1983
                {
1984
                    String message = hostname + "/" + rtagId + "/" + daemon + "/" + logBase + ".log";
1985
                    throw new BuildException( message );
1986
                }
1987
                else
1988
                {
1989
                    throw new BuildException();
1990
                }
1991
            }
1992
 
1993
        }
1994
    }
1995
 
1996
 
1997
    /**
1998
     * Delete a directory and all of its contents
1999
     * Set directories and sub directories writable in case the user has messed with permissions. 
2000
     * This function is called recursively to delete the entire directory tree
2001
     * 
2002
     * Note: Having some issues deleting directories
2003
     *       Try many times. On the second attempt log the files that remained
2004
     * 
2005
     * @param directory The top level directory to delete
2006
     */
2007
    private void deleteDirectory(File directory)
2008
    {
2009
        logMsg("deleteDirectory " + directory.getName(), DEBUG);
2010
 
2011
        int attempts = 0;
2012
        boolean verbose = false;
2013
        while (directory.exists()) {
2014
            attempts++;
2015
 
2016
            // Use Java native method fist
2017
            // The Jats utility is good, but there is some interaction with VirusScanners/Indexing that a bit strange
2018
            //
2019
            if ( (attempts & 1) == 1) {
2020
                deleteDirectoryInternalViaJava(directory, verbose);
2021
            }  else {
2022
                deleteDirectoryInternalViaJats(directory, verbose);
2023
            }
2024
 
2025
            if (!directory.exists()) {
2026
                logMsg("deleteDirectory deleted after " + attempts + " attempts " + directory.getName(), FATAL);
2027
                break;
2028
            }
2029
            verbose = true;
2030
 
2031
            if (attempts > 10)
2032
            {
2033
                logMsg("deleteDirectory give up delete after " + attempts + " attempts " + directory.getName(), FATAL);
2034
                break;
2035
            }
2036
 
2037
            logMsg("deleteDirectory not deleted after " + attempts + " attempts " + directory.getName(), FATAL);
2038
 
2039
//          //
2040
//          //  Debugging code
2041
//          //  Display all handles in the system (windows only)
2042
//          //
2043
//          if(System.getProperty("os.name").startsWith("Windows"))
2044
//          {
2045
//              String[] cmd = {"handle"};
2046
//              Log("deleteDirectory Execute handle.", warn);
2047
//              thread.setCommandline(cmd);
2048
//              try {
2049
//                  thread.execute();
2050
//              } catch (IOException e) {
2051
//                  logMsg("deleteDirectory Did not execute handle: " + e.getMessage(), WARN);
2052
//              }
2053
//          }
2054
 
2055
            //  Wait a short while before attempting to delete the directory again
2056
            //  Rational:
2057
            //      - AntiVirus software may be having a sniff, so let it finish
2058
            //      - Program shut down may take a few seconds
2059
            //      - Because nothing else appears to work
2060
            try {
2061
                logMsg("deleteDirectory sleep before attempt:" + attempts, DEBUG);
2062
                Thread.sleep(10 * 1000L);
2063
            } catch (InterruptedException e) {
2064
                logMsg("deleteDirectory sleep exception: " + e.getMessage(), WARN);
2065
                Thread.currentThread().interrupt();
2066
                break;
2067
            }
2068
 
2069
        }
2070
    }
2071
 
2072
    /**
2073
     * The body of the deleteDirectory operation
2074
     * Used simply to avoid excessive logging.
2075
     * 
2076
     * @param directory The top level directory to delete
2077
     * @param verbose - display files and folders as they are deleted
2078
     */
2079
    private void deleteDirectoryInternalViaJava(File directory, boolean verbose)
2080
    {
2081
        try
2082
        {
2083
            if ( directory.exists() )
2084
            {
2085
                File[] children = directory.listFiles();
2086
                directory.setWritable(true);
2087
                if ( children != null )
2088
                {
2089
                    for ( int child=0; child < children.length; child++ )
2090
                    {
2091
                        if ( children[ child ].isDirectory() )
2092
                        {
2093
                            deleteDirectoryInternalViaJava( children[ child ], verbose );
2094
                        }
2095
                        else
2096
                        {
2097
                            if(verbose)
2098
                            {
2099
                                logMsg("deleteDirectory File:" + children[ child ].getName(), DEBUG);
2100
                            }
2101
                            children[ child ].setWritable(true);
2102
                            children[ child ].delete();
2103
                        }
2104
                    }
2105
                }
2106
                if (verbose)
2107
                {
2108
                    logMsg("deleteDirectory Dir:" + directory.getName(), DEBUG);
2109
                }
2110
                directory.delete();
2111
            }
2112
        }
2113
        catch( SecurityException e )
2114
        {
2115
            // this can be thrown by exists and delete
2116
            logMsg("deleteDirectory caught SecurityException", WARN);
2117
        }
2118
    }
2119
 
2120
 
2121
    /**
2122
     * The body of the deleteDirectory operation done with JATS utility
2123
     * Used simply to avoid excessive logging.
2124
     * 
2125
     * @param directory The top level directory to delete
2126
     * @param verbose - display files and folders as they are deleted
2127
     */
2128
    private void deleteDirectoryInternalViaJats(File directory, boolean verbose)
2129
    {
2130
 
2131
        //  Use jats ebin JatsFileUtil T0 TextMsg DirName to delete the directory tree
2132
        //  Address issues that cannot be solved in java
2133
 
2134
        command.init("jats", "ebin","JatsFileUtil" );
2135
        command.add( verbose, "T9" );
2136
        command.add( !verbose, "T0" );
2137
        command.add( "DeleteDir-" + rtagId );
2138
        command.add(directory.getAbsolutePath());
2139
 
2140
        // Run the command - don't care if it fails
2141
        //  It should not generate an exception
2142
        try {
2143
            runCommand(null);
2144
        } catch (Exception e1) {
2145
            logMsg("deleteDirectory caught Exception", ERROR);
2146
        }
2147
    }
2148
 
2149
    /**
2150
     * Insert a marker into the created package so that the
2151
     * escrow build can detect that the package has been built.
2152
     * 
2153
     * This is used in the following situations:
2154
     * 
2155
     * 1) ANT packages that could be build on multiple machines
2156
     * 2) Restarted build on the same machine
2157
     */
2158
    private void insertEscrowMarker()
2159
    {
2160
        //
2161
        //  Only used in escrow mode
2162
        //
2163
        if ( daemon == null && packageStandard == BuildStandards.ANT)
2164
        {
2165
            //
2166
            //  ANT builds are performed on a machine type basis
2167
            //  Create a 'MachClass' based marker
2168
            //
2169
            String destination = utilities.catDir(dpkgArchive, packageName, packageFullVersion);
2170
            String filename = "built." + gbeMachClass; 
2171
 
2172
            try
2173
            {
2174
                new File(destination).mkdirs(); 
2175
                new File(destination, filename).createNewFile();
2176
            } 
2177
            catch (IOException ioe)
2178
            {
2179
                logMsg("Cannot insert Escrow Marker", FATAL);
2180
            }
2181
        }
2182
    }
2183
 
2184
 
2185
    /**
2186
     * Check for the existence of an Escrow marker
2187
     * Used so that the build system can detect if this
2188
     * package has already been built.
2189
     * 
2190
     * Can occur under two conditions
2191
     * 
2192
     * 1) ANT packages that can be built on multiple machines
2193
     * 2) ReStarted build on same machine 
2194
     *  
2195
     * Assumption: Only called in Escrow Mode 
2196
     * 
2197
     * @return TRUE  - Marker Detected
2198
     *         FALSE - Marker not Detected
2199
     */
2200
    private boolean checkEscrowMarker() throws Exception
2201
    {
2202
        String destination = utilities.catDir(dpkgArchive, packageName, packageFullVersion);
2203
        String filename = "built." + (generic ? "generic" : hostname);
2204
 
2205
        if (new File( destination, filename ).exists())
2206
        {
2207
            return true;
2208
        }
2209
 
2210
        if ( packageStandard == BuildStandards.ANT)
2211
        {
2212
            //
2213
            //  ANT builds are performed on a machine type basis
2214
            //  Check for a 'MachClass' based marker
2215
            //
2216
            filename = "built." + gbeMachClass; 
2217
            if (new File( destination, filename).exists())
2218
            {
2219
                return true;
2220
            }
2221
        }
2222
        return false;
2223
    }
2224
 
2225
    //---------------------------------------------------------------------------
2226
    //    Extend the <abt> task with several new elements
2227
    //
2228
    //        <depend package_alias="${debian_dpkg.cots}"/>
2229
    //        <buildinfo gbe_machtype="solaris10_x86" method="jats" arg="debug"/>
2230
    //
2231
    public Depend createDepend()
2232
    {
2233
        Depend depend = new Depend();
2234
        dependCollection.add(depend);
2235
        return depend;
2236
    }
2237
 
2238
    public BuildInfo createBuildInfo()
2239
    {
2240
        BuildInfo buildInfo = new BuildInfo();
2241
        buildInfoCollection.add(buildInfo);
2242
        return buildInfo;
2243
    }
2244
 
2245
}