Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
814 mhunt 1
package com.erggroup.buildtool.daemon;
2
 
3
import com.erggroup.buildtool.daemon.ResumeTimerTask;
4
import com.erggroup.buildtool.ripple.ReleaseManager;
868 mhunt 5
import com.erggroup.buildtool.smtp.Smtpsend;
6
import com.erggroup.buildtool.ripple.RippleEngine;
896 mhunt 7
import com.erggroup.buildtool.ripple.MutableString;
814 mhunt 8
 
9
import java.io.BufferedReader;
10
import java.io.File;
11
import java.io.FileNotFoundException;
12
import java.io.FileOutputStream;
13
import java.io.FileWriter;
14
import java.io.FilenameFilter;
15
 
16
import java.io.IOException;
17
import java.io.PrintStream;
18
import java.io.StringReader;
19
 
20
import java.sql.SQLException;
21
 
22
import java.util.Date;
23
import java.util.Timer;
24
 
25
import org.apache.log4j.Logger;
26
import org.apache.tools.ant.BuildException;
27
import org.apache.tools.ant.DefaultLogger;
28
import org.apache.tools.ant.Project;
29
import org.apache.tools.ant.ProjectHelper;
30
 
31
/**Build Thread sub component
32
 */
33
public abstract class BuildThread
34
  extends Thread
35
{
36
  /**baseline identifier (which release manager release this BuildThread is dealing with)
37
   * @attribute
38
   */
39
  protected int mRtagId = 0;
40
 
41
  /**unique identifier of this BuildThread
42
   * @attribute
43
   */
44
  protected int mRconId = 0;
45
 
46
  /**
47
   * @aggregation composite
48
   */
49
  protected RunLevel mRunLevel;
50
 
51
  /**
52
   * @aggregation composite
53
   */
54
  protected ReleaseManager mReleaseManager;
55
 
56
  /**configured GBEBUILDFILTER for this BuildThread
57
   * @attribute
58
   */
896 mhunt 59
  protected String mGbebuildfilter = null;
814 mhunt 60
 
896 mhunt 61
  /**unit test support
62
   * @attribute
63
   */
64
  protected String mUnitTest = "";
65
 
814 mhunt 66
  /**
67
   * @aggregation composite
68
   */
69
  protected static ResumeTimerTask mResumeTimerTask;
70
 
71
  /**
72
   * @aggregation composite
73
   */
74
  private static Timer mTimer;
75
 
76
  /**Synchroniser object
77
   * Use to Synchronize on by multiple threads
78
   * @attribute
79
   */
80
  static final Object mSynchroniser = new Object();
81
 
82
  /**BuildThread group
83
   * @attribute
84
   */
85
  public static final ThreadGroup mThreadGroup = new ThreadGroup("BuildThread");
86
 
87
  /**the advertised build file content when either
88
   * a) no package in the baseline has a build requirement
89
   * b) the next package in the baseline with a build requirement is generic
90
   * @attribute
91
   */
92
  protected static final String mDummyBuildFileContent = new String("<dummy/>");
93
 
94
  /**Set true when last build cycle was benign.
95
   * @attribute
96
   */
97
  protected boolean mSleep;
98
 
886 mhunt 99
  /**Set true when last build cycle caught SQLException or Exception.
100
   * @attribute
101
   */
102
  protected boolean mException;
103
 
854 mhunt 104
  /**Set true when ant error reported on any target.
105
   * @attribute
106
   */
107
  private boolean mErrorReported;
108
 
866 mhunt 109
  /**Logger
854 mhunt 110
   * @attribute
111
   */
866 mhunt 112
  private static final Logger mLogger = Logger.getLogger(BuildThread.class);
854 mhunt 113
 
866 mhunt 114
  /**Package name for reporting purposes.
814 mhunt 115
   * @attribute
116
   */
866 mhunt 117
  protected String mReportingPackageName;
814 mhunt 118
 
866 mhunt 119
  /**Package version for reporting purposes.
120
   * @attribute
121
   */
122
  protected String mReportingPackageVersion;
123
 
124
  /**Package extension for reporting purposes.
125
   * @attribute
126
   */
127
  protected String mReportingPackageExtension;
128
 
129
  /**Package location for reporting purposes.
130
   * @attribute
131
   */
132
  protected String mReportingPackageLocation;
133
 
134
  /**Package dependencies for reporting purposes.
135
   * @attribute
136
   */
137
  protected String mReportingPackageDepends;
138
 
139
  /**Is ripple flag for reporting purposes.
140
   * @attribute
141
   */
142
  protected String mReportingIsRipple;
143
 
144
  /**Package version identifier for reporting purposes.
145
   * @attribute
146
   */
147
  protected String mReportingPackageVersionId;
148
 
149
  /**Fully published flag for reporting purposes.
150
   * @attribute
151
   */
152
  protected String mReportingFullyPublished;
153
 
154
  /**New label for reporting purposes.
155
   * @attribute
156
   */
157
  protected String mReportingNewLabel;
158
 
159
  /**Source control interaction for reporting purposes.
160
   * @attribute
161
   */
162
  protected String mReportingDoesNotRequireSourceControlInteraction;
163
 
908 mhunt 164
  /**Source control interaction for reporting purposes.
165
   * @attribute
166
   */
167
  protected String mReportingTestBuild;
168
 
866 mhunt 169
  /**Log file location for reporting purposes.
170
   * @attribute
171
   */
172
  protected String mReportingBuildFailureLogFile;
173
 
868 mhunt 174
  /**Non null determines to only gather metrics
175
   * @attribute
176
   */
177
  protected static final String mGbeGatherMetricsOnly = System.getenv("GBE_GATHER_METRICS");
178
 
896 mhunt 179
  /**Non null determines to only gather metrics
180
   * @attribute
181
   */
182
  protected boolean mRecoverable;
183
 
814 mhunt 184
  /**constructor
185
   */
186
  BuildThread()
187
  {
188
    super(mThreadGroup, "");
189
    mLogger.debug("BuildThread");
190
    mSleep = false;
886 mhunt 191
    mException = false;
854 mhunt 192
    mErrorReported = false;
814 mhunt 193
    mReleaseManager = new ReleaseManager();
896 mhunt 194
    mRecoverable = false;
814 mhunt 195
 
196
    // no need to be synchronized - BuildThreads are instantiated in a single thread
197
    if ( mResumeTimerTask == null )
198
    {
199
      mResumeTimerTask = new ResumeTimerTask();
200
      mTimer = new Timer();
201
      mResumeTimerTask.setTimer(mTimer);
202
    }
203
  }
204
 
886 mhunt 205
  /**sleeps when mException is set
206
   */
207
  protected void sleepCheck()
208
  {
209
    if (mException)
210
    {
211
      try
212
      {
213
        Integer sleepTime = 300000;
214
        mLogger.warn("sleepCheck sleep " + sleepTime.toString() + " secs");
215
        Thread.sleep(sleepTime);
216
        mLogger.info("sleepCheck sleep returned");
217
      }
218
      catch(InterruptedException e)
219
      {
220
        mLogger.warn("sleepCheck sleep caught InterruptedException");
221
      }
222
 
223
    }
224
    mException = false;
225
  }
226
 
814 mhunt 227
  /**initially changes the run level to IDLE
228
   * determines if the BuildThread is still configured
229
   * a) determines if the BuildThread is running in scheduled downtime
230
   * b) determines if the BuildThread is directed to pause
231
   * changes the run level to PAUSED if a) or b) are true
232
   * throws ExitException when not configured
233
   * implements the sequence diagrams allowed to proceed, not allowed to proceed, exit
234
   */
868 mhunt 235
  protected void allowedToProceed(boolean master) throws ExitException, SQLException, Exception
814 mhunt 236
  {
237
    mLogger.debug("allowedToProceed");
886 mhunt 238
 
239
    try
240
    {
241
      mRunLevel = RunLevel.IDLE;
242
      mLogger.warn("allowedToProceed changing run level to IDLE for rcon_id " + mRconId);
916 mhunt 243
      mLogger.fatal("allowedToProceed calling mRunLevel.persist on IDLE");                      
886 mhunt 244
      mRunLevel.persist(mReleaseManager, mRconId);
896 mhunt 245
      if ( master )
246
      {
916 mhunt 247
        mLogger.fatal("allowedToProceed calling mReleaseManager.discardVersion");                      
896 mhunt 248
        mReleaseManager.discardVersion();
249
      }
916 mhunt 250
      mLogger.fatal("allowedToProceed calling mReleaseManager.clearCurrentPackageBeingBuilt");                      
886 mhunt 251
      mReleaseManager.clearCurrentPackageBeingBuilt(mRconId);      
252
    }
253
    catch(SQLException e)
254
    {
255
      mLogger.warn("allowedToProceed caught SQLException");
256
    }
814 mhunt 257
 
258
    if (mSleep)
259
    {
260
      try
261
      {
868 mhunt 262
        Integer sleepTime = 300000;
263
 
264
        if ( !master )
265
        {
266
          // sleep only 3 secs on slave
267
          sleepTime = 3000;
268
        }
269
        mLogger.warn("allowedToProceed sleep " + sleepTime.toString() + " secs no build requirement");
916 mhunt 270
        mLogger.fatal("allowedToProceed calling Thread.sleep for 3 secs");                      
868 mhunt 271
        Thread.sleep(sleepTime);
814 mhunt 272
        mLogger.info("allowedToProceed sleep returned");
273
      }
274
      catch(InterruptedException e)
275
      {
276
        mLogger.warn("allowedToProceed sleep caught InterruptedException");
277
      }
278
    }
279
 
280
    boolean proceed = false;
281
 
898 mhunt 282
    try
814 mhunt 283
    {
898 mhunt 284
      while ( !proceed )
814 mhunt 285
      {
916 mhunt 286
        mLogger.fatal("allowedToProceed calling mReleaseManager.connect");                      
898 mhunt 287
        mReleaseManager.connect();
916 mhunt 288
        mLogger.fatal("allowedToProceed calling mReleaseManager.queryReleaseConfig");                      
898 mhunt 289
        if ( !mReleaseManager.queryReleaseConfig(mRtagId, mRconId, BuildDaemon.mHostname, getMode()) )
290
        {
291
          mReleaseManager.disconnect();
292
          mLogger.warn("allowedToProceed queryReleaseConfig failed");
293
          throw new ExitException();
294
        }
814 mhunt 295
 
898 mhunt 296
        Date resumeTime = new Date( 0 );
916 mhunt 297
        mLogger.fatal("allowedToProceed calling mReleaseManager.queryRunLevelSchedule");                      
898 mhunt 298
        if ( !mReleaseManager.queryRunLevelSchedule(resumeTime, mRecoverable) )
814 mhunt 299
        {
898 mhunt 300
          mLogger.info("allowedToProceed scheduled downtime");
301
          mReleaseManager.disconnect();
302
          mRunLevel = RunLevel.PAUSED;
303
          mLogger.warn("allowedToProceed changing run level to PAUSED for rcon_id " + mRconId);
304
          mRunLevel.persist(mReleaseManager, mRconId);
305
 
306
          synchronized(mSynchroniser)
814 mhunt 307
          {
898 mhunt 308
            // contain the schedule and wait in the same synchronized block to prevent a deadlock
309
            // eg this thread calls schedule, timer thread calls notifyall, this thread calls wait (forever)
310
            try
814 mhunt 311
            {
898 mhunt 312
              if (mResumeTimerTask.isCancelled())
313
              {
314
                mResumeTimerTask = new ResumeTimerTask();
315
                mTimer = new Timer();
316
                mResumeTimerTask.setTimer(mTimer);
317
              }
318
              mLogger.warn("allowedToProceed schedule passed " + resumeTime.getTime());
319
              mTimer.schedule(mResumeTimerTask, resumeTime);
814 mhunt 320
            }
898 mhunt 321
            catch( IllegalStateException e )
814 mhunt 322
            {
898 mhunt 323
              // this may be thrown by schedule if already scheduled
324
              // it signifies another BuildThread has already scheduled the ResumeTimerTask
325
               mLogger.warn("allowedToProceed already scheduled");
814 mhunt 326
            }
898 mhunt 327
 
328
            try
329
            {
330
              mLogger.warn("allowedToProceed wait");
331
              mSynchroniser.wait();
332
              mLogger.warn("allowedToProceed wait returned");
333
 
334
              if ( mUnitTest.compareTo("unit test not allowed to proceed") == 0 )
335
              {
336
                throw new ExitException();
337
              }
338
            }
339
            catch( InterruptedException e )
340
            {
341
              mLogger.warn("allowedToProceed caught InterruptedException");
342
            }
814 mhunt 343
          }
898 mhunt 344
 
814 mhunt 345
        }
898 mhunt 346
        else
814 mhunt 347
        {
916 mhunt 348
          mLogger.fatal("allowedToProceed calling mReleaseManager.queryDirectedRunLevel");                      
898 mhunt 349
          if ( !mReleaseManager.queryDirectedRunLevel(mRconId) )
814 mhunt 350
          {
898 mhunt 351
            mLogger.info("allowedToProceed downtime");
352
            mReleaseManager.disconnect();
353
            mRunLevel = RunLevel.PAUSED;
354
            mLogger.warn("allowedToProceed changing run level to PAUSED for rcon_id " + mRconId);
355
            mRunLevel.persist(mReleaseManager, mRconId);
356
            try
357
            {
358
              // to do, sleep for periodicMs
359
              mLogger.warn("allowedToProceed sleep 5 mins directed downtime");
360
              Thread.sleep(300000);
361
              mLogger.info("allowedToProceed sleep returned");
362
            }
363
            catch (InterruptedException e)
364
            {
365
              mLogger.warn("allowedToProceed caught InterruptedException");
366
            }
814 mhunt 367
          }
898 mhunt 368
          else
814 mhunt 369
          {
898 mhunt 370
            mReleaseManager.disconnect();
371
            proceed = true;
814 mhunt 372
          }
373
        }
374
      }
375
    }
898 mhunt 376
    finally
377
    {
378
      // this block is executed regardless of what happens in the try block
379
      // even if an exception is thrown
380
      // ensure disconnect
916 mhunt 381
      mLogger.fatal("allowedToProceed calling mReleaseManager.disconnect");                      
898 mhunt 382
      mReleaseManager.disconnect();
383
    }
896 mhunt 384
 
385
    mRecoverable = false;
814 mhunt 386
  }
387
 
388
  /**periodically 
389
   * a) performs disk housekeeping
390
   * b) determines if a minimum threshold of disk space is available
894 mhunt 391
   * c) determines if a file can be touched
814 mhunt 392
   * changes the run level to CANNOT_CONTINUE if insufficient disk space
393
   * otherwise changes the run level to ACTIVE and returns
394
   * implements the sequence diagram check environment
395
   */
396
  protected void checkEnvironment() throws Exception
397
  {
398
    mLogger.debug("checkEnvironment");
399
    boolean exit = false;
400
 
401
    while( !exit )
402
    {
403
      housekeep();
404
 
405
      // attempt to exit
406
      exit = true;
407
 
894 mhunt 408
      if ( !hasSufficientDiskSpace() || !touch() )
814 mhunt 409
      {
894 mhunt 410
        mLogger.warn("checkEnvironment below disk free threshold or read only file system detected");
814 mhunt 411
        exit = false;
412
        mRunLevel = RunLevel.CANNOT_CONTINUE;
816 mhunt 413
        mLogger.warn("checkEnvironment changing run level to CANNOT_CONTINUE for rcon_id " + mRconId);
814 mhunt 414
        mRunLevel.persist(mReleaseManager, mRconId);
415
        try
416
        {
417
          // to do, sleep for periodicMs
896 mhunt 418
          if ( mUnitTest.compareTo("unit test check environment") != 0 )
814 mhunt 419
          {
420
            mLogger.warn("checkEnvironment sleep 5 mins below disk free threshold");
421
            Thread.sleep(300000);
422
            mLogger.info("checkEnvironment sleep returned");
423
          }
424
        }
425
        catch (InterruptedException e)
426
        {
427
          mLogger.warn("checkEnvironment caught InterruptedException");
428
        }
429
      }
430
    }
431
 
432
    mRunLevel = RunLevel.ACTIVE;    
816 mhunt 433
    mLogger.warn("checkEnvironment changing run level to ACTIVE for rcon_id " + mRconId);
814 mhunt 434
    mRunLevel.persist(mReleaseManager, mRconId);
435
  }
436
 
437
  /**performs disk housekeeping which involves deleting build directories > 5 days old
438
   * refer to the sequence diagram check environment
439
   */
440
  private void housekeep()
441
  {
442
    mLogger.debug("housekeep");
443
    FilenameFilter filter = new FilenameFilter()
444
    {
445
      public boolean accept(File file, String name)
446
      {
447
        mLogger.debug("accept " + name);
448
        boolean retVal = false;
449
 
450
        if ( file.isDirectory() && !name.startsWith( "." ) )
451
        {
452
          retVal = true;
453
        }
454
 
455
        mLogger.info("accept returned " + retVal);
456
        return retVal;
457
      }
458
    };
459
 
460
    try
461
    {
842 mhunt 462
      // DEVI 46729, 46730, solaris 10 core dumps implicate deleteDirectory
463
      // let each BuildThread look after its own housekeeping
854 mhunt 464
      File ocwd = new File( BuildDaemon.mGbeLog );
465
      File hcwd = new File( ocwd, BuildDaemon.mHostname );
466
      File cwd = new File( hcwd, String.valueOf( mRtagId ) );
842 mhunt 467
 
814 mhunt 468
      File[] children = cwd.listFiles( filter );
469
 
470
      if ( children != null )
471
      {
472
        for ( int child=0; child < children.length; child++ )
473
        {
854 mhunt 474
          // child is named uniquely to encapsulate a build
475
          // 5 days = 432,000,000 milliseconds
476
          if ( ( System.currentTimeMillis() - children[ child ].lastModified() ) > 432000000 )
814 mhunt 477
          {
854 mhunt 478
            // the directory is over 5 days old
479
            mLogger.warn("housekeep deleting directory " + children[ child ].getName());
896 mhunt 480
            if ( mUnitTest.compareTo("unit test check environment") != 0 )
814 mhunt 481
            {
854 mhunt 482
              deleteDirectory( children[ child ] );
814 mhunt 483
            }
484
          }
485
        }
486
      }
487
    }
488
    catch( SecurityException e )
489
    {
490
      // this can be thrown by lastModified
894 mhunt 491
      mLogger.warn("housekeep caught SecurityException");
814 mhunt 492
    }
493
 
494
  }
495
 
894 mhunt 496
  /**returns true if a file exists and can be deleted,
497
   * created and exists in the file system
498
   * this is to guard against read-only file systems
499
   */
500
  private boolean touch()
501
  {
502
    mLogger.debug("touch");
503
    boolean retVal = true;
504
 
505
    try
506
    {
507
      File touch = new File( String.valueOf( mRtagId ) + "touch" );
508
 
509
      if ( touch.exists() )
510
      {
511
        // delete it
512
        retVal = touch.delete();
513
      }
514
 
515
      if ( retVal )
516
      {
517
        // file does not exist
518
        retVal = touch.createNewFile();
519
      }
520
    }
521
    catch( SecurityException e )
522
    {
523
      // this can be thrown by exists, delete, createNewFile
524
      retVal = false;
525
      mLogger.warn("touch caught SecurityException");
526
    }
527
    catch( IOException e )
528
    {
529
      // this can be thrown by createNewFile
530
      retVal = false;
531
      mLogger.warn("touch caught IOException");
532
    }
533
 
534
    mLogger.info("touch returned " + retVal);
535
    return retVal;
536
  }
537
 
814 mhunt 538
  /**returns true if free disk space > 10G
539
   * this may become configurable if the need arises
540
   * refer to the sequence diagram check environment
541
   */
542
  private boolean hasSufficientDiskSpace()
543
  {
544
    mLogger.debug("hasSufficientDiskSpace");
545
    boolean retVal = true;
546
    long freeSpace = 0;
547
 
548
    try
549
    {
550
      File cwd = new File( "." );
551
 
552
      // 5G = 5368709120 bytes
886 mhunt 553
      // 1G = 1073741824 bytes - useful for testing
896 mhunt 554
      if ( mUnitTest.compareTo("unit test check environment") == 0 )
814 mhunt 555
      {
864 mhunt 556
        if ( ReleaseManager.mPersistedRunLevelCollection.size() == 0 )
814 mhunt 557
        {
558
          retVal = false;
559
        }
560
        else
561
        {
562
          retVal = true;
563
        }
564
      }
565
      else
566
      {
816 mhunt 567
        freeSpace = cwd.getUsableSpace();
814 mhunt 568
 
569
        if ( freeSpace < 5368709120L )
570
        {
816 mhunt 571
          mLogger.warn("hasSufficientDiskSpace on " + cwd.getAbsolutePath() + " freeSpace " + freeSpace);
814 mhunt 572
          retVal = false;
573
        }
574
      }
575
    }
576
    catch( SecurityException e )
577
    {
578
      // this can be thrown by getFreeSpace
579
       mLogger.warn("hasSufficientDiskSpace caught SecurityException");
580
    }
581
 
582
    mLogger.info("hasSufficientDiskSpace returned " + retVal + " " + freeSpace);
583
    return retVal;
584
  }
585
 
586
  /**abstract method
587
   */
588
  public abstract void run();
589
 
590
  /**deletes directory and all its files
591
   */
592
  protected void deleteDirectory(File directory)
593
  {
594
    mLogger.debug("deleteDirectory " + directory.getName());
595
    try
596
    {
597
      if ( directory.exists() )
598
      {
599
        FilenameFilter filter = new FilenameFilter()
600
        {
601
          public boolean accept(File file, String name)
602
          {
603
            mLogger.debug("accept " + name);
604
            boolean retVal = false;
605
 
840 mhunt 606
            if ( name.compareTo(".") != 0 && ( name.compareTo("..") != 0 ) )
814 mhunt 607
            {
608
              retVal = true;
609
            }
610
 
611
            mLogger.info("accept returned " + retVal);
612
            return retVal;
613
          }
614
        };
615
 
616
        File[] children = directory.listFiles( filter );
617
 
618
        if ( children != null )
619
        {
620
          for ( int child=0; child < children.length; child++ )
621
          {
622
            if ( children[ child ].isDirectory() )
623
            {
624
              deleteDirectory( children[ child ] );
625
            }
626
            else
627
            {
628
              children[ child ].delete();
629
            }
630
          }
631
        }
632
        directory.delete();
633
      }
634
    }
635
    catch( SecurityException e )
636
    {
637
      // this can be thrown by exists and delete
638
       mLogger.warn("deleteDirectory caught SecurityException");
639
    }
640
  }
641
 
642
  /**abstract method
643
   */
644
  protected abstract char getMode();
645
 
646
  /**injects GBE_BUILDFILTER into the passed buildFileContent
647
   * builds a buildFile from the buildFileContent
648
   * triggers ant to operate on the buildFile
649
   */
854 mhunt 650
  protected void deliverChange(String buildFileContent, String target, boolean master)
814 mhunt 651
  {
652
    mLogger.debug("deliverChange");
854 mhunt 653
 
902 mhunt 654
    // always perform a AbtSetUp and AbtTearDown
655
    if ( ( target == null && mErrorReported ) || ( target == "AbtPublish" && mErrorReported ) )
854 mhunt 656
    {
902 mhunt 657
      // AbtSetUp or the build failed
866 mhunt 658
      // the default target will inevitably fail and will generate further email if allowed to proceed
659
      // do not mask the root cause
854 mhunt 660
      return;
661
    }
662
 
814 mhunt 663
    File buildFile = new File(mRtagId + "build.xml");
862 mhunt 664
    boolean logError = true;
866 mhunt 665
    Project p = new Project();
814 mhunt 666
 
667
    try
668
    {
669
      // clear the file contents
670
      if ( buildFileContent != null && target != null && target.compareTo("AbtSetUp") == 0 )
671
      {
672
        FileOutputStream buildFileOutputStream = new FileOutputStream(buildFile, false);
673
        buildFileOutputStream.close();
674
 
675
        StringReader buildFileContentStringReader = new StringReader(buildFileContent);
676
        BufferedReader buildFileBufferedReader = new BufferedReader(buildFileContentStringReader);
677
 
678
        // sanitise the buildFileContent
679
        // it may contain line.separators of "\n", "\r", or "\r\n" variety, depending on the location of the ripple engine
680
        String sanitisedBFC = new String();
681
        String lf = new String( System.getProperty("line.separator") );
682
        int lineCount = 0;
683
        String line = new String();
684
 
685
        while( ( line = buildFileBufferedReader.readLine() ) != null)
686
        {
687
          sanitisedBFC += line + lf;
688
          lineCount++;
689
 
690
          if ( lineCount == 2 )
691
          {
692
            // have read the first two lines
862 mhunt 693
            String inject = "<property name=\"abt_MASTER\" value=\"";
814 mhunt 694
 
695
            if ( master )
696
            {
697
              inject += "yes\"/>" + lf;
698
            }
699
            else
700
            {
701
              inject += "no\"/>" + lf;
702
            }
896 mhunt 703
 
814 mhunt 704
            // insert a GBE_BUILDFILTER property if necessary
896 mhunt 705
            if ( mGbebuildfilter != null && mGbebuildfilter.length() > 0 )
814 mhunt 706
            {
862 mhunt 707
              inject += "<property name=\"abt_GBE_BUILDFILTER\" value=\"" + mGbebuildfilter + "\"/>" + lf;
814 mhunt 708
            }
709
 
710
            mLogger.info("deliverChange injecting " + inject);
711
            sanitisedBFC += inject;
712
          }
713
        }
714
        buildFileBufferedReader.close();
715
        FileWriter buildFileWriter = new FileWriter(buildFile);
716
        buildFileWriter.write(sanitisedBFC);
717
        buildFileWriter.close();
718
      }
719
 
866 mhunt 720
      mReportingPackageName = null;
721
      mReportingPackageVersion = null;
722
      mReportingPackageExtension = null;
723
      mReportingPackageLocation = null;
724
      mReportingPackageDepends = null;
725
      mReportingIsRipple = null;
726
      mReportingPackageVersionId = null;
727
      mReportingDoesNotRequireSourceControlInteraction = null;
908 mhunt 728
      mReportingTestBuild = null;
866 mhunt 729
      mReportingFullyPublished = null;
730
      mReportingNewLabel = null;
731
 
732
      if ( buildFile.exists() )
814 mhunt 733
      {
866 mhunt 734
        p.setProperty("ant.file", buildFile.getAbsolutePath());
735
        DefaultLogger dl = new DefaultLogger();
736
        PrintStream ps = new PrintStream(mRtagId + ".log");
737
        dl.setOutputPrintStream(ps);
738
        dl.setMessageOutputLevel(Project.MSG_INFO);
739
        p.addBuildListener(dl);
740
        p.init();
741
        ProjectHelper pH = ProjectHelper.getProjectHelper();
742
        p.addReference("ant.projectHelper", pH);
743
 
744
        // parse can throw BuildException, this is serious
745
        pH.parse(p, buildFile);
746
        mLogger.warn("deliverChange ant launched on " + buildFile.getAbsolutePath());
747
 
748
        if ( target == null )
749
        {
750
          target = p.getDefaultTarget();
751
        }
752
        mLogger.warn("deliverChange ant launched against target " + target);
753
 
754
        // executeTarget can throw BuildException, this is not serious
755
        logError = false;
756
        // set up project properties for reporting purposes
757
        // this first group are hard coded in the build file
758
        mReportingPackageName = p.getProperty("abt_package_name");
759
        mReportingPackageVersion = p.getProperty("abt_package_version");
760
        mReportingPackageExtension = p.getProperty("abt_package_extension");
761
        mReportingPackageLocation = p.getProperty("basedir") + p.getProperty("abt_package_location");
762
        mReportingPackageDepends = p.getProperty("abt_package_depends");
763
        mReportingIsRipple = p.getProperty("abt_is_ripple");
764
        mReportingPackageVersionId = p.getProperty("abt_package_version_id");
765
        mReportingDoesNotRequireSourceControlInteraction = p.getProperty("abt_does_not_require_source_control_interaction");
908 mhunt 766
        mReportingTestBuild = p.getProperty("abt_test_build_instruction");
866 mhunt 767
 
768
        p.executeTarget(target);
769
        mLogger.warn("deliverChange ant returned");
770
 
814 mhunt 771
      }
772
    }
773
    catch( BuildException e )
774
    {
862 mhunt 775
      if ( logError )
776
      {
777
        mLogger.error("deliverChange caught BuildException, the build failed " + e.getMessage());
778
      }
779
      else
780
      {
866 mhunt 781
        if ( mReportingBuildFailureLogFile == null )
782
        {
783
          mReportingBuildFailureLogFile = e.getMessage();
784
        }
785
        mLogger.debug("deliverChange caught BuildException, big deal, the build failed " + mReportingBuildFailureLogFile);
862 mhunt 786
      }
854 mhunt 787
 
788
      mErrorReported = true;
814 mhunt 789
    }
790
    catch( FileNotFoundException e )
791
    {
792
      mLogger.error("deliverChange caught FileNotFoundException");
793
    }
794
    catch( IOException e )
795
    {
796
      mLogger.error("deliverChange caught IOException");
797
    }
798
 
866 mhunt 799
    // this group are set at run time (by the AbtPublish target only)
800
    // they will be null for every other target,
801
    // and null if an error occurs in the AbtPublish target
802
    mReportingFullyPublished = p.getProperty("abt_fully_published");
803
    mReportingNewLabel = p.getProperty("abt_new_label");
804
 
814 mhunt 805
  }
806
 
807
  /**sets up a ClearCase static view
808
   */
896 mhunt 809
  protected void setViewUp(String content, boolean master) throws SQLException, Exception
814 mhunt 810
  {
811
    mLogger.debug("setViewUp");
866 mhunt 812
    mReportingBuildFailureLogFile = null;
854 mhunt 813
    mErrorReported = false;
868 mhunt 814
 
815
    if ( !master && mGbeGatherMetricsOnly != null )
816
    {
817
      // do not run AbtSetUp on slave in metrics gathering mode
818
      return;
819
    }
820
 
896 mhunt 821
    MutableString buildFilter = new MutableString();
822
    mReleaseManager.queryBuildFilter(mRconId, buildFilter);
823
    mGbebuildfilter = buildFilter.value;
824
 
814 mhunt 825
    // run ant on the AbtSetUp target
826
    deliverChange(content, "AbtSetUp", master);
827
  }
828
 
829
  /**Checks the archive for the <packageName>/<packageVersion>/built.<machtype> existence
830
   */
831
  protected boolean published(String archive, String packageName, 
832
                            String packageVersion, String machtype,
833
                            String generic)
834
  {
835
    mLogger.debug("published");
836
    boolean retVal = false;
837
 
838
    String fs = System.getProperty( "file.separator" );
839
    String destination = archive + fs + packageName + fs + packageVersion;
840
 
841
    mLogger.debug("published " + destination);
842
    String filename = "built.";
843
 
844
    if ( generic.compareTo("generic") == 0 )
845
    {
846
      filename += "generic";
847
    }
848
    else
849
    {
850
      filename += machtype;
851
    }
852
 
853
    mLogger.debug("published " + filename);
854
    File flag = new File( destination, filename );
855
 
856
    if ( flag.exists() )
857
    {
858
      retVal = true;
859
    }
860
    mLogger.debug("published returned " + retVal);
861
    return retVal;
862
  }
868 mhunt 863
 
864
  /**
865
   * indefinite pause notification
866
  */
867
   protected void indefinitePause(RippleEngine rippleEngine, String cause)
868
   {
869
     mLogger.debug("indefinitePause");
870
 
871
     String body =
872
     "Hostname: " + BuildDaemon.mHostname + "<p>" +
873
     "Release: " + rippleEngine.mBaselineName + "<p>" +
874
     cause;
875
 
876
     try
877
     {
878
       Smtpsend.send(
879
       rippleEngine.mMailServer, // mailServer
880
       rippleEngine.mMailSender, // source
881
       rippleEngine.mGlobalTarget, // target
882
       null, // cc
883
       null, // bcc
884
       "BUILD DAEMON INDEFINITE PAUSE", // subject
885
       body, // body
886
       null // attachment
887
       );
888
     }
889
     catch( Exception e )
890
     {
891
     }
892
   }
893
 
814 mhunt 894
}