Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
263 dpurdie 1
########################################################################
4549 dpurdie 2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
227 dpurdie 3
#
5499 dpurdie 4
# Module name   : create_dpkg.pl
4549 dpurdie 5
# Module type   : Makefile system
263 dpurdie 6
# Compiler(s)   : Perl
4549 dpurdie 7
# Environment(s): jats
227 dpurdie 8
#
263 dpurdie 9
# Description   : This script is used to create a dpkg_archive.
5527 dpurdie 10
#                 Features:
4549 dpurdie 11
#                   * No user interaction
5527 dpurdie 12
#                   * Generates files list for ReleaseNote integration
13
#                   * Can generate package fragemts as a tarball for build system
227 dpurdie 14
#
4549 dpurdie 15
# Usage:        : See POD
227 dpurdie 16
#
263 dpurdie 17
#......................................................................#
227 dpurdie 18
 
4549 dpurdie 19
 
263 dpurdie 20
require 5.008_002;
227 dpurdie 21
 
22
# Include Standard Perl Functions
23
#
24
use strict;
263 dpurdie 25
use warnings;
227 dpurdie 26
use Cwd;
27
use Getopt::Long;
28
use File::Basename;
29
use File::Find;
30
use File::Path;
31
use File::Copy;
32
use Pod::Usage;
263 dpurdie 33
use Digest::MD5;
4549 dpurdie 34
use XML::Simple;
4633 dpurdie 35
use Encode qw(decode encode);
227 dpurdie 36
 
37
use JatsError;
263 dpurdie 38
use JatsEnv;
227 dpurdie 39
use DescPkg;
40
use FileUtils;
5527 dpurdie 41
use JatsSystem;
227 dpurdie 42
 
363 dpurdie 43
#
44
#   Under Windows we need the Win32::FileSecurity module
45
#   It only exists under windows
46
#
47
my $Win32 = eval "require Win32::FileSecurity";
48
 
227 dpurdie 49
# define Global variables
50
#
4549 dpurdie 51
my $VERSION = "3.0.0";
227 dpurdie 52
my $PROGNAME = "create_dpkg.pl";
53
 
279 dpurdie 54
# Globals imported from environment
55
#
56
our $GBE_MACHTYPE;
57
our $GBE_HOSTNAME;
58
our $USER;
59
our $GBE_ABT;
227 dpurdie 60
 
279 dpurdie 61
# Global variables
62
#
227 dpurdie 63
my $DPKG_NAME     = "";
64
my $DESC_NAME     = "";
65
my $DPKG_VERSION  = "";
66
my $DESCPKG_FILE  = "";
67
my $DESCPKG_TYPE  = "";
68
my $CWD_DIR       = cwd;
69
my $SRC_ROOT;
70
my $DPKG_DIR;
71
my $DPKG_ROOT;
4003 dpurdie 72
my $PKG_BASE;
263 dpurdie 73
my $bad_merge_count = 0;
4424 dpurdie 74
my @bad_symlinks;
4549 dpurdie 75
my @fileList;
76
my $descPkgCount = 0;
227 dpurdie 77
 
78
#
79
#   Option variables
80
#
81
my $opt_help = 0;
82
my $opt_manual = 0;
83
my $opt_verbose = 0;
84
my $opt_quiet = 0;
4549 dpurdie 85
my $opt_delete = 0;
227 dpurdie 86
my $opt_override = 0;
87
my $opt_merge = 0;
88
my $opt_archive;
89
my $opt_generic;
90
my $opt_pname;
91
my $opt_pversion;
92
my $opt_test;
263 dpurdie 93
my $opt_md5 = 1;
4549 dpurdie 94
my $opt_outfile;
95
my $opt_info;
5527 dpurdie 96
my $opt_tarmode;
97
my $opt_testArchive;
5550 dpurdie 98
my $opt_noBuild;
227 dpurdie 99
 
100
 
101
#
102
#   Structure to translate -archive=xxx option to archive variable
103
#   These are the various dpkg_archives known to JATS
104
#
4688 dpurdie 105
my %Archive2Var =( 'main'      => 'GBE_DPKG',
106
                   'store'     => 'GBE_DPKG_STORE',
107
                   'cache'     => 'GBE_DPKG_CACHE',
108
                   'local'     => 'GBE_DPKG_LOCAL',
109
                   'sandbox'   => 'GBE_DPKG_SBOX',
110
                   'deploy'    => 'GBE_DPLY',
111
                   'replica'   => 'GBE_DPKG_REPLICA',
227 dpurdie 112
                   );
113
 
114
#------------------------------------------------------------------------------
115
#------------------------------------------------------------------------------
116
# Subroutines
117
#------------------------------------------------------------------------------
118
#------------------------------------------------------------------------------
119
 
120
#------------------------------------------------------------------------------
121
sub LogFileOp
122
#
123
# Description:
124
#       This sub-routine is used to generate a consistent informational log
125
#------------------------------------------------------------------------------
126
{
127
    my ($opr, $file) = @_;
5532 dpurdie 128
    $file =~ s/\Q$DPKG_ROOT\E/DPKG/;
129
    $file =~ s/\Q$SRC_ROOT\E/PKG/;
227 dpurdie 130
 
131
    Information (sprintf( "%-15s [%s]", $opr, $file));
132
}
133
 
4549 dpurdie 134
#-------------------------------------------------------------------------------
135
# Function        : addFile 
136
#
137
# Description     : Add a file to the list of transferred files
138
#
139
# Inputs          : $type           - File type
140
#                   $source         - Source file - full path
141
#                                     Use local copy, not network copy for file ops
142
#                   $target         - Target file name
143
#                   $md5sum         - Precalculated MD5 sum 
144
#
145
# Returns         : 
146
#
147
sub addFile
148
{
149
    my ($type, $source, $target, $md5sum) = @_;
150
    my %data;
151
 
152
    if ((not defined $md5sum) && ($type eq 'file'))
153
    {
154
        Verbose("Calculate MD5 Digest: $source");
155
        open(my $fh , $source) or Error ("Can't open '$source': $!");
156
        binmode $fh, ':crlf';
157
        $md5sum = Digest::MD5->new->addfile($fh)->hexdigest;
158
        close $fh;
159
    }
160
 
5532 dpurdie 161
    $target =~ s~\Q$DPKG_DIR\E~~;
4549 dpurdie 162
    $target =~ s~^/~~;
163
    $target =~ s~/$~~;
164
 
4633 dpurdie 165
    #
166
    #   Convert from iso-8859-1 into utf-8
167
    #
168
    $target = decode( 'iso-8859-1', $target );
169
    $target = encode( 'utf-8', $target );
170
 
4549 dpurdie 171
    if ($type eq 'dir')
172
    {
173
        $data{path} = $target;
174
    }
175
    else
176
    {
177
        $data{path} = StripFileExt($target);
178
        $data{name} = StripDir($target);
179
        if ($type eq 'file')
180
        {
181
            $data{size} = (stat($source))[7];
182
            $data{md5sum} = $md5sum;
183
        }
184
    }
185
 
186
    $data{fullname} = $target;
187
    $data{type} = $type;
188
    $data{machtype} = $GBE_MACHTYPE;
189
    $data{host} = $GBE_HOSTNAME;
190
 
5499 dpurdie 191
    # Put a nice '/' on the end of the path elements
4549 dpurdie 192
    $data{path} .= '/'
193
        if ( exists ($data{path}) && length($data{path}) > 0);
194
 
195
    push @fileList, \%data;
196
}
197
 
198
#-------------------------------------------------------------------------------
199
# Function        : writeFileInfo 
200
#
201
# Description     : Write out an XML file that contains this processes
202
#                   contribution to the output package 
203
#
5527 dpurdie 204
# Inputs          : $targetDir          - Base directory for the file 
4549 dpurdie 205
#
206
# Returns         : 
207
#
208
sub writeFileInfo
209
{
5527 dpurdie 210
    my ($targetDir) = @_;
4549 dpurdie 211
    my $data;
212
    $data->{file} = \@fileList;
213
 
214
    #
215
    #   Write out sections of XML
216
    #       Want control over the output order
217
    #       Use lots of attributes and only elements for arrays
218
    #       Save as one attribute per line - for readability
219
    #
5527 dpurdie 220
    $opt_outfile = $opt_generic ? "built.files.generic.xml" : "built.files.$GBE_HOSTNAME.xml";
221
    $opt_outfile = catfile( $targetDir, $opt_outfile); 
4549 dpurdie 222
 
223
    LogFileOp ('Meta File', $opt_outfile);
224
    my $xs = XML::Simple->new( NoAttr =>0, AttrIndent => 1 );
225
 
226
    open (my $XML, '>', $opt_outfile) || Error ("Cannot create output file: $opt_outfile", $!);
227
    $xs->XMLout($data, 
228
                'RootName' => 'files', 
229
                'XMLDecl'  => '<?xml version="1.0" encoding="UTF-8"?>',
230
                'OutputFile' => $XML);
231
    close $XML;
232
 
233
}
234
 
227 dpurdie 235
#------------------------------------------------------------------------------
236
sub Init
237
#
238
# Description:
239
#     This function is used to process any command line arguements
240
#     and print the start banner.
241
#
242
#------------------------------------------------------------------------------
243
{
244
    # Process any command line arguements...
245
    my $result = GetOptions (
5527 dpurdie 246
                'help:+'        => \$opt_help,              # flag, multiple use allowed
247
                'manual:3'      => \$opt_help,              # flag
248
                'verbose:+'     => \$opt_verbose,           # flag, multiple use allowed
249
                'override!'     => \$opt_override,          # [no]flag (No longer used. Backward compat with build tool)
250
                'delete!'       => \$opt_delete,            # [no]flag
251
                'merge|m!'      => \$opt_merge,             # [no]flag.
252
                'archive=s'     => \$opt_archive,           # string
253
                'quiet+'        => \$opt_quiet,             # Flag
254
                'generic!'      => \$opt_generic,           # [no]Flag
255
                'pname=s'       => \$opt_pname,             # string
256
                'pversion=s'    => \$opt_pversion,          # string
257
                'test!'         => \$opt_test,              # [no]flag
258
                'md5!'          => \$opt_md5,               # [no]flag
259
                'info!'         => \$opt_info,              # [no]flag
260
                'tarmode!'      => \$opt_tarmode,           # [no]flag
261
                'testArchive'   => \$opt_testArchive,       # [no]flag
5550 dpurdie 262
                'nobuild'       => \$opt_noBuild,           # flag
227 dpurdie 263
                );
264
 
265
 
266
    #
267
    #   Process help and manual options
268
    #
269
    pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
270
    pod2usage(-verbose => 1)  if ($opt_help == 2 );
263 dpurdie 271
    pod2usage(-verbose => 2)  if ($opt_help > 2);
227 dpurdie 272
 
273
    #
274
    #   Init the error and message subsystem
275
    #
276
    ErrorConfig( 'name'    =>'CREATE_DPKG',
277
                 'verbose' => $opt_verbose,
278
                 'quiet'   => $opt_quiet );
279
 
280
    if ($opt_verbose)
281
    {
282
       Verbose ("Program: $PROGNAME");
283
       Verbose ("Version: $VERSION");
284
    }
285
 
286
    #
263 dpurdie 287
    #   Needed EnvVars
288
    #
289
    EnvImport ('GBE_MACHTYPE');
279 dpurdie 290
    EnvImport ('GBE_HOSTNAME');
291
    EnvImport ('USER' );
292
    EnvImportOptional ('GBE_ABT', "");
263 dpurdie 293
 
4003 dpurdie 294
    #
295
    #   Determine the target archive
296
    #   The default archive is GBE_DPKG, but this may be changed
297
    #
298
    $opt_archive = 'main' unless ( $opt_archive );
299
    my $archive_tag = $Archive2Var{$opt_archive};
300
    Error("Unknown archive specified: $opt_archive")
301
        unless ( $archive_tag );
302
    $DPKG_ROOT = $ENV{$archive_tag} || '';
303
    Verbose ("Archive Variable: $archive_tag" );
304
    Verbose2 ("Archive Path: $DPKG_ROOT" );
279 dpurdie 305
 
263 dpurdie 306
    #
5527 dpurdie 307
    #   Append testArchive path
308
    #
309
    $DPKG_ROOT = catdir ($DPKG_ROOT, '.dpkg_archive', 'test_dpkg') if $opt_testArchive;
310
 
311
    #
4003 dpurdie 312
    #   Detect NoBuild marker
313
    #   This will bypass most of the operation of this package
314
    #
5550 dpurdie 315
    $opt_noBuild = 2 if -f 'noBuild.gbe';
316
    if ( $opt_noBuild)
4003 dpurdie 317
    {
318
        Verbose ("No Build Marker file found");
319
        Error("Use of noBuild marker should only be done by a build daemon")
320
            unless ( $GBE_ABT );
321
 
322
        $SRC_ROOT = '';
323
        $DPKG_NAME = 'pkg';
324
        $DESCPKG_FILE = 'descpkg';
325
        $PKG_BASE =$CWD_DIR;
5550 dpurdie 326
 
327
        Error("NoBuild operation requires package name and version") unless ($opt_pname && $opt_pversion);
328
        $DPKG_NAME = $opt_pname;
329
        $DPKG_VERSION = $opt_pversion;
330
 
4003 dpurdie 331
        return;
332
    }
333
 
334
    #
227 dpurdie 335
    #   Check for a "pkg" directory
336
    #   This may be in:
337
    #       1) The deploy directory (DEPLOY) build/deploy/descpkg
338
    #       2) The build directory (ANT)     build/pkg/descpkg
339
    #       3) The current directory (JATS)  pkg/xxxx/descpkg
340
    #
4003 dpurdie 341
    $PKG_BASE = "$CWD_DIR/build/deploy";
227 dpurdie 342
    Verbose2 ("Looking for descpkg: $PKG_BASE");
343
    if ( -f "$PKG_BASE/descpkg" )
344
    {
345
        #
346
        #   This is a deployment package.
347
        #   Force the use of the GBE_DPLY
348
        #
349
        $opt_archive = 'deploy' unless ( $opt_archive );
350
    }
351
    else
352
    {
353
        $PKG_BASE = "$CWD_DIR/build/pkg";
354
        Verbose ("Looking for descpkg: $PKG_BASE");
355
        if ( ! -f  "$PKG_BASE/descpkg" )
356
        {
357
            $PKG_BASE = "$CWD_DIR/pkg";
358
            Verbose ("Looking for descpkg: $PKG_BASE");
359
            Error("Failed to find a package to transfer. Looked in:",
360
                  "./build/deploy",
361
                  "./build/pkg",
362
                  "./pkg"
363
                  )
364
                unless( -d $PKG_BASE );
365
        }
366
    }
367
    Verbose("Package directory: $PKG_BASE");
368
 
369
    Error("Repository location not specified: $archive_tag")
370
        unless $DPKG_ROOT;
371
 
372
    Error("Failed to find Repository: $DPKG_ROOT")
373
        unless ( -d $DPKG_ROOT );
374
 
375
    #   Locate the package
376
    #   Packages are located by looking for a file called descpkg within the
377
    #   main package directory.
378
    #
379
    #   This installation process only handles one such file
380
    #
4549 dpurdie 381
    $descPkgCount = 0;
227 dpurdie 382
    File::Find::find( \&pkgFind, $PKG_BASE);
4549 dpurdie 383
 
384
    if ($descPkgCount > 1 )
385
    {
386
        Warning ("Package contains multiple ($descPkgCount) descpkg files");
387
    }
4003 dpurdie 388
}
227 dpurdie 389
 
4003 dpurdie 390
#-------------------------------------------------------------------------------
391
# Function        : CheckDescPkg
392
#
393
# Description     : Check the descpkg file
394
#
395
# Inputs          : Globals
396
#
397
# Returns         : Will not return on error
398
#
399
sub CheckDescPkg
400
{
5550 dpurdie 401
    #
402
    #   Don't need a package description if performing a no-build
403
    #   The package name and version will be provided on the command line
404
    #   NoBuilds MUST NOT package up a descpkg file
405
    #
406
    return if ($opt_noBuild);
407
 
227 dpurdie 408
    # Get the dpkg_archive version number we are  going to create.
409
    #
410
    Error("Descpkg file not found in package directory: $PKG_BASE")
411
        unless ( -f "$DESCPKG_FILE" );
412
 
413
    #
414
    #   Read in the package description and validate essential fields
415
    #
416
    GetDpkgArchiveVersion($DESCPKG_FILE);
417
    unless ( "$DPKG_VERSION" )
418
    {
419
        Error ("Incorrect descpkg content detected.",
420
               "Check JATS build.pl config.");
421
    }
422
 
423
    #
424
    #   Need to support two forms of pkg subdirectory
425
    #       1) packages are in a named subdir within 'pkg'
426
    #       2) package is within 'pkg' or 'deploy'
427
    #
428
    if ( $DPKG_NAME eq 'pkg' || $DPKG_NAME eq 'deploy' )
429
    {
430
        $DPKG_NAME = $DESC_NAME;
431
        unless ( $DESC_NAME )
432
        {
433
            Error ("Cannot determine package name",
434
                   "The packages 'descpkg' file is bad or missing");
435
        }
436
    }
437
    elsif ( $DESC_NAME ne $DPKG_NAME )
438
    {
439
        Error ("Package name MUST match package description",
440
               "Check build.pl and package.pl",
441
               "Package name: $DPKG_NAME",
442
               "Description : $DESC_NAME" );
443
    }
444
 
445
    #
446
    # lets just check to see if we have a version number before
447
    # we proceed.
448
    #
449
    unless ( $DPKG_VERSION )
450
    {
451
        Error("Cannot determine dpkg_archive version number.",
452
              "Check JATS build config.");
453
    }
454
 
455
    #
456
    #   Sanity test package name and version, if provided
457
    #
458
    if ( $opt_pname )
459
    {
460
        ReportError ("Package Name does not match expected name",
461
                     "Expected: '$opt_pname'",
462
                     "Descpkg : '$DPKG_NAME'") unless ( $DPKG_NAME eq $opt_pname );
463
    }
464
    if ( $opt_pversion )
465
    {
466
        ReportError ("Package Version does not match expected version",
467
                     "Expected: '$opt_pversion'",
468
                     "Descpkg : '$DPKG_VERSION'") unless ( $DPKG_VERSION eq $opt_pversion );
469
    }
470
    ErrorDoExit();
4003 dpurdie 471
}
227 dpurdie 472
 
4003 dpurdie 473
#-------------------------------------------------------------------------------
474
# Function        : ShowInfo
475
#
476
# Description     : Show info to the user
477
#
478
# Inputs          : 
479
#
480
# Returns         : 
481
#
482
sub ShowInfo
483
{
227 dpurdie 484
    #
485
    #   Set up the target directory path and name
486
    #   It will be created later
487
    #
5527 dpurdie 488
    if ($opt_tarmode)
489
    {
490
        $DPKG_DIR = catdir($DPKG_ROOT, '.dpkg_archive', 'fragments');
491
    }
492
    else
493
    {
494
        $DPKG_DIR = catdir($DPKG_ROOT, $DPKG_NAME, $DPKG_VERSION );
495
    }
4003 dpurdie 496
 
227 dpurdie 497
    #
498
    #   Information for the user
499
    #
500
    Information ("---------------------------------------------------------------");
501
    Information ("Dpkg archive creation tool...");
502
    Information ("Version: $VERSION");
503
    Information ("");
504
    Information ("Information:");
505
    Information ("Working dir   = [$CWD_DIR]");
506
    Information ("Package Root  = [$SRC_ROOT]");
4549 dpurdie 507
    Information ("Repository    = [$DPKG_ROOT]");
508
    Information ("                *Non Standard archive") unless $opt_archive eq 'main';
227 dpurdie 509
    Information ("Target dir    = [$DPKG_DIR]");
510
    Information1("DPKG_NAME     = [$DPKG_NAME]");
511
    Information1("DPKG_VERSION  = [$DPKG_VERSION]");
512
    Information1("GBE_MACHTYPE  = [$GBE_MACHTYPE]");
279 dpurdie 513
    Information1("GBE_HOSTNAME  = [$GBE_HOSTNAME]");
514
    Information1("GBE_ABT       = [$GBE_ABT]");
515
    Information1("USER          = [$USER]");
5550 dpurdie 516
    Information ("")                                if ( $opt_merge || $opt_delete || $opt_info || $opt_tarmode || $opt_testArchive || $opt_noBuild);
517
    Information ("Opt:NoBuild       = Enabled")     if ( $opt_noBuild );
5527 dpurdie 518
    Information ("Opt:TarMode       = Enabled")     if ( $opt_tarmode );
519
    Information ("Opt:Delete        = Enabled")     if ( $opt_delete );
520
    Information ("Opt:Merge         = Enabled")     if ( $opt_merge );
521
    Information ("Opt:testArchive   = Enabled")     if ( $opt_testArchive );
522
    Information ("Opt:TestMode      = Enabled. No Package Transferred") if ( $opt_test );
523
    Information ("Opt:Info          = Enabled. No Package Transferred") if ( $opt_info );
524
    Warning     ("Sandbox Build     = Yes") if ($ENV{GBE_DPKG_SBOX}) ;
227 dpurdie 525
    Information ("---------------------------------------------------------------");
526
 
369 dpurdie 527
    #
528
    #   If the environment variable GBE_DPKG_SBOX is defined then the package
529
    #   is being built within a development sandbox. In such a sandbox the
530
    #   version numbers of the packages are ignored. Publishing a package
5499 dpurdie 531
    #   from such an environment is certainly not reproducible - so don't allow
369 dpurdie 532
    #   it to happen
533
    #
534
    #   Allow versions of 99.99.99 as these are known to be test versions
535
    #
536
    unless ( $opt_archive eq 'local' || $opt_archive eq 'sandbox' )
537
    {
538
        if ( $ENV{GBE_DPKG_SBOX} )
539
        {
540
            unless ( $DPKG_VERSION =~ /^99.99.99/ )
541
            {
542
                Error("Cannot not publish a package that has been generated",
543
                   "within a Sandbox as the version of dependent packages",
544
                   "is not guaranteed.",
545
                   "Only version 99.99.99 is allowed");
546
            }
547
        }
548
    }
4003 dpurdie 549
}
369 dpurdie 550
 
551
 
227 dpurdie 552
#------------------------------------------------------------------------------
553
sub pkgFind
554
#
555
# Description:
235 dpurdie 556
#     This subroutine is used to locate the FIRST descpkg file in
227 dpurdie 557
#     the local pkg dir.
558
#
559
#------------------------------------------------------------------------------
560
{
561
    my($item)= "$File::Find::name";
562
    my($file)= File::Basename::basename($item);
563
 
564
    # we get the absolute path from the find, but we only require
565
    # a relative path from the starting dir.
566
    # so our start dir.
567
 
568
    # we need to determine which file we are dealing with
235 dpurdie 569
    if ( ! -d $item && $file =~ /^descpkg$/ )
227 dpurdie 570
    {
4549 dpurdie 571
        $descPkgCount++;
572
 
235 dpurdie 573
        #
574
        #   Only grab the first one
575
        #
576
        if ( $DESCPKG_FILE )
577
        {
5532 dpurdie 578
            $item =~ s~\Q$PKG_BASE\E/~~;
4549 dpurdie 579
            Verbose ("Multiple descpkg files:", $item );
235 dpurdie 580
            return;
581
        }
582
 
227 dpurdie 583
        $DESCPKG_FILE = $item;
584
        my($dir)= File::Basename::dirname($item);
585
        $DPKG_NAME = File::Basename::basename($dir);
586
        $SRC_ROOT = $dir;
587
    }
588
}
589
 
590
 
591
#------------------------------------------------------------------------------
592
sub GetDpkgArchiveVersion
593
#
594
# Description:
595
#     This subroutine is used to determine the version of the dpkg_archive.
596
#     We assume that the version number is in the descpkg file.
597
#
598
#     Need to allow for two forms of descpkg. Some one decided that a Java
599
#     Manifest would be a good descpkg file - a long time after the rest of the
600
#     world had been using an existing file format.
601
#
602
#     Lines are tagged
603
#
604
#     Once the version number is determined we set the
605
#     global DPKG_VERSION variable.
606
#
607
#------------------------------------------------------------------------------
608
{
609
    my ($path) = @_;
610
    my $line;
611
    my $type;
612
 
613
    #
614
    #   Use a common routine to parse the package descriptor
615
    #   There are several forms that may need to be processed
616
    #
617
    my $pkg_data = ReadDescpkg( $path );
618
    Error("Failed to open file [$path].") unless $pkg_data;
619
 
620
    $DESC_NAME    = $pkg_data->{'NAME'};
621
    $DPKG_VERSION = $pkg_data->{'VERSION_FULL'};
622
}
623
 
624
#-------------------------------------------------------------------------------
625
# Function        : TransferDescpkg
626
#
627
# Description     : Copy and process the descpkg file to the target
628
#
629
# Inputs          :
630
#
631
# Returns         :
632
#
633
sub TransferDescpkg
634
{
635
    my $result = CopyDescpkg( @_ );
636
    Error("Transfer descpkg: $result") if ( $result );
637
}
638
 
639
#------------------------------------------------------------------------------
640
sub CreateDpkgArchive
641
#
642
# Description:
643
#     This subroutine is used to create the dpkg_archive in the $DPKG_ROOT
644
#     location 
645
#
4969 dpurdie 646
#     We use the global DPKG_ROOT, DPKG_DIR, DPKG_NAME, and DPKG_VERSION
227 dpurdie 647
#     to create the required directory structure.
648
#
649
#     If the dpkg_archive is new (ie not a new version) it is assumed the user
650
#     has access to create the top level dir for the new dpkg_archive.
651
#
652
#     The new dpkg_archive is created with the permission of the user 
653
#     executing this script.
654
#
655
#     If an error ocurs during the dpkg_archive creation the script
656
#     will terminate.
657
#
658
#------------------------------------------------------------------------------
659
{
263 dpurdie 660
    #
227 dpurdie 661
    # first we need to ensure we have the top level directory
662
    #
663
    if ( -d $DPKG_DIR )
664
    {
665
        Warning("Detected previous dpkg_archive [$DPKG_DIR]");
4549 dpurdie 666
        Error ("Package already exists and Package merging not selected")
667
            unless ( $opt_delete || $opt_merge );
263 dpurdie 668
 
669
        #
670
        #   Target exists
671
        #   Unless we are merging, we need to blow the entire tree away
672
        #
673
        unless ( $opt_merge )
674
        {
675
            LogFileOp("Remove Prev Pkg",$DPKG_DIR);
676
            rmtree($DPKG_DIR);
677
 
678
            #
679
            #   At this point the target directory 'should not' exist
680
            #   but it may. Some packges (like JATS) have Unix links within
681
            #   dpkg_archive filesystem. These cannot be deleted under windows
682
            #
683
            #   Not nice, but we live with it.
684
            #
685
            Warning ("Unable to delete previous instance of the package")
686
                if ( -d $DPKG_DIR );
687
        }
227 dpurdie 688
    }
689
    Information("");
690
 
691
    #
692
    #   Create the top level directory
693
    #
694
    mkpath($DPKG_DIR, 0, 0775);
695
 
696
    #
4003 dpurdie 697
    #   Transfer source directory, unless this is a noBuild
698
    #
699
    if ( $SRC_ROOT ne '' )
227 dpurdie 700
    {
4003 dpurdie 701
        # Process the files
702
        #
703
        if ( -d $SRC_ROOT )
704
        {
705
            File::Find::find( \&pkgFind2, $SRC_ROOT );
263 dpurdie 706
 
4424 dpurdie 707
            if (@bad_symlinks)
708
            {
709
                my $msg = "Bad Symlinks: " . scalar @bad_symlinks;
710
                $opt_test ? ReportError($msg, @bad_symlinks) : Warning($msg, @bad_symlinks);
711
            }
712
 
4003 dpurdie 713
            if ( $bad_merge_count )
714
            {
715
                my $msg = "Merged files that differ: $bad_merge_count";
4424 dpurdie 716
                $opt_md5 ? ReportError($msg) : Warning($msg);
4003 dpurdie 717
            }
4424 dpurdie 718
            ErrorDoExit();
4003 dpurdie 719
        }
720
        else
263 dpurdie 721
        {
4003 dpurdie 722
            Error("Failed to find dir [$SRC_ROOT]",
723
                  "Check JATS config.");
263 dpurdie 724
        }
227 dpurdie 725
    }
726
 
727
    #
728
    #   Transfer of data is complete
4424 dpurdie 729
    #       Mark the archive with the build machine to indicate which parts of
730
    #       a multi-machine build have been performed
227 dpurdie 731
    #
5527 dpurdie 732
    my $touchfile = createBuiltFile($DPKG_DIR);
4634 dpurdie 733
    addFile('file', $touchfile, $touchfile);
227 dpurdie 734
 
735
    #
736
    #   If there is a .lnk file in the archive then remove it now that the
737
    #   archive has been transferred. The .lnk files are created in 'local'
738
    #   archives in order to simplify multi-package builds
739
    #
740
    my $link_file = "$DPKG_ROOT/$DPKG_NAME/$DPKG_VERSION.lnk";
741
    if ( -f $link_file )
742
    {
743
        LogFileOp("Removing Link",$link_file);
744
        unlink $link_file;
745
    }
746
 
4969 dpurdie 747
    #
5527 dpurdie 748
    #   Create the MD5 info file
749
    #   
750
    writeFileInfo($DPKG_DIR);
227 dpurdie 751
    return 1;
752
}
753
 
754
#------------------------------------------------------------------------------
755
sub pkgFind2
756
#
757
# Description:
758
#   This subroutine is used to locate all associated pkg files in
759
#   the local pkg dir.
760
#
761
#   This routine is called for each file and directory within the package
762
#   Some files and directories are treated in a special manner
763
#       - Top level directory is ignored
764
#
765
#
766
#
767
#------------------------------------------------------------------------------
768
{
769
    my $item = $File::Find::name;
770
    my $base = File::Basename::basename($item);
771
 
772
    #
773
    #   Calculate the target directory name
774
    #
775
    my $target = $item;
241 dpurdie 776
    $target = $DPKG_DIR . substr ( $item, length ($SRC_ROOT) );
227 dpurdie 777
 
778
    if ( -d $item )
779
    {
780
        #
781
        #   Ignore the top level directory
782
        #   It has already been created
783
        #
784
        return
785
            if ( $item eq $SRC_ROOT );
786
 
787
        #
788
        #   Directories are handled differently
789
        #       - Directories are created with nice permissions
263 dpurdie 790
        #       - If the directory already exists then it is being merged.
227 dpurdie 791
        #
792
        if ( ! -d "$target" )
793
        {
794
            LogFileOp("Creating Dir", $target);
795
            mkpath("$target", 0, 0775);
4549 dpurdie 796
            addFile('dir', $item , $target);
227 dpurdie 797
        }
798
    }
799
    else
800
    {
801
        #
802
        #   File copy
803
        #   If merging then do not overwrite an existing file
804
        #
805
        unless ( $opt_merge && -f $target )
806
        {
807
            if ( $item =~ m~/descpkg$~ )
808
            {
809
                LogFileOp("Rewrite File",$target);
4549 dpurdie 810
                TransferDescpkg( $item, $target );
363 dpurdie 811
                CORE::chmod oct("0664"), $target;
4549 dpurdie 812
                addFile('file', $item, $target);
227 dpurdie 813
            }
814
            else
815
            {
816
                #
817
                #   Copy file to destination
818
                #   If the file is a link, then duplicate the link contents
819
                #   Use: Unix libraries are created as two files:
820
                #        lib.xxxx.so -> libxxxx.so.vv.vv.vv
821
                #
822
                if ( -l $item )
823
                {
4424 dpurdie 824
                    if (-f $item)
227 dpurdie 825
                    {
4424 dpurdie 826
                        LogFileOp("Copying Link", $target);
827
                        my $link = readlink $item;
828
                        Verbose( "Link: $item, $link");
829
                        symlink ($link, $target );
830
                        unless ( $link && -l $target )
831
                        {
832
                            Error("Failed to copy link [$item] to [$target]: $!");
833
                        }
4549 dpurdie 834
                        addFile('link', $item , $target);
227 dpurdie 835
                    }
4424 dpurdie 836
                    else
837
                    {
838
                        # Don't copy broken Symlinks
839
                        # Perhaps this should be an error - but is will break escrow builds
840
                        #
841
                        LogFileOp("Broken SymLink", $target);
842
                        push @bad_symlinks, substr ( $item, 1+length ($SRC_ROOT) );
843
                    }
227 dpurdie 844
                }
845
                elsif (File::Copy::copy($item, $target))
846
                {
847
                    LogFileOp("Copying File",$target);
363 dpurdie 848
                    #
849
                    #   Mark the file as executable by all
850
                    #   Under windows, this is tricky
851
                    #
852
                    if ( $Win32 )
853
                    {
854
                        my %hash;
855
                        $hash{Everyone} = Win32::FileSecurity::MakeMask( qw( FULL  ) );
856
                        Win32::FileSecurity::Set( $target, \%hash );
857
                    }
858
                    else
859
                    {
860
                        CORE::chmod oct("0775"), $target;
861
                    }
4549 dpurdie 862
                    addFile('file', $item, $target);
227 dpurdie 863
                }
864
                else
865
                {
866
                    Error("Failed to copy file [$item] to [$target]: $!");
867
                }
868
            }
869
        }
870
        else
871
        {
872
            #
873
            #   Merging packages
874
            #   Ensure that the descpkg file is "touched" so that caches
875
            #   that use this file as a timestamp can be updated
876
            #
877
            if ( $item =~ m~/descpkg$~ )
878
            {
879
                LogFileOp("Touch File",$target);
880
                TouchFile( $target ) && Error ( "Failed to touch: $target" );
4549 dpurdie 881
                addFile('merge', $item, $target);
227 dpurdie 882
            }
883
            else
884
            {
263 dpurdie 885
                #
886
                #   MD5 digest the files that are being merged
887
                #   Ignore version_*.h files as these are generated
888
                #   and may contain different dates and line endings
889
                #
267 dpurdie 890
                #   Don't put the files into 'binmode'
891
                #   Need to handle some level of Unix/DOS file endings
892
                #
893
                #
263 dpurdie 894
                my $msg = "Merge Skip File";
895
                unless ( $target =~ m~/version[^/]*\.h$~ )
896
                {
897
                    $msg = "Merge Test File";
898
                    #
899
                    #   Compare the two files with an MD5
900
                    #
901
                    local *FILE;
902
                    open(FILE, $target) or Error ("Can't open '$target': $!");
267 dpurdie 903
                    binmode FILE, ':crlf';
263 dpurdie 904
                    my $target_md5 = Digest::MD5->new->addfile(*FILE)->hexdigest;
905
                    close FILE;
906
 
907
                    open(FILE, $item) or Error ("Can't open '$item': $!");
267 dpurdie 908
                    binmode FILE, ':crlf';
263 dpurdie 909
                    my $source_md5 = Digest::MD5->new->addfile(*FILE)->hexdigest;
910
                    close FILE;
911
 
912
                    unless ( $source_md5 eq $target_md5 )
913
                    {
914
                        $msg = "DIFF: Merge Test File";
915
                        $bad_merge_count ++;
916
                    }
4549 dpurdie 917
                    addFile('merge', $item, $target, $target_md5);
263 dpurdie 918
                }
919
                LogFileOp($msg,$target);
227 dpurdie 920
            }
921
        }
922
    }
923
}
924
 
925
#-------------------------------------------------------------------------------
5527 dpurdie 926
# Function        : CreateDpkgArchiveTarBall 
927
#
928
# Description     : Similar to CreateDpkgArchive, but it will create a tar file within the target
929
#                   directory.
930
#                   
931
#                   This is used by the build system to:
932
#                       1) Greatly speedup the transfer of packages with a very large number of files
933
#                       2) Remove the need for an multi-filesytem, multi OS atomic lock on the package
934
#                       
935
#                   The build system will process the tarball and create the package archive
936
#                   In doing so it will handle merge errors
937
#
938
# Inputs          : 
939
#
940
# Returns         : 
941
#
942
sub CreateDpkgArchiveTarBall
943
{
944
    Information("");
945
    InitFileUtils();
946
 
947
 
948
    #
949
    #   Locate the tar utility
950
    #   Use gtar if its available otherwise use tar
951
    #   
952
    my $tarProg = LocateProgInPath('gtar', '--All');
953
    $tarProg = LocateProgInPath('tar', '--All') unless $tarProg;
954
    Error ("Tar utility not found in path") unless $tarProg;
955
 
956
    #
957
    #   If a 'noBuild' then create a dummy package directory simply
958
    #   to contain the metadata. 
959
    #   Delete any existing dir of the same name to ensure its clean.
960
    #
961
    if ( $SRC_ROOT eq '' )
962
    {
963
        $SRC_ROOT = AbsPath('pkg/noBuild');
964
        RmDirTree ($SRC_ROOT);
965
        mkpath($SRC_ROOT, 0, 0775);
966
    }
967
 
968
    #
969
    #   Mark the archive with the build machine to indicate which parts of
970
    #   a multi-machine build have been performed
971
    #
972
    createBuiltFile($SRC_ROOT);
973
 
974
    #   Process the source directory
975
    #   A NoBuild will contain one metafile
976
    #
977
    if ( -d $SRC_ROOT )
978
    {
979
        File::Find::find( \&pkgFindTarBall, $SRC_ROOT );
980
 
981
        if (@bad_symlinks)
982
        {
983
            my $msg = "Bad Symlinks: " . scalar @bad_symlinks;
984
            $opt_test ? ReportError($msg, @bad_symlinks) : Warning($msg, @bad_symlinks);
985
        }
986
        ErrorDoExit();
987
    }
988
    else
989
    {
990
        Error("Failed to find dir [$SRC_ROOT]",
991
              "Check JATS config.");
992
    }
993
 
994
    #
995
    #   Create the MD5 info file
996
    #   
997
    writeFileInfo($SRC_ROOT);
998
 
999
    #
1000
    #   Create the target path in the target archive
1001
    #
1002
    LogFileOp ('Creating', $DPKG_DIR);
1003
    mkpath($DPKG_DIR, 0, 0775);
1004
 
1005
 
1006
    #
1007
    #   Create the TAR file
1008
    #   Use gzip compression (tar.gz) as it provides a good compromise bewteen speed and size
1009
    #
1010
    my $tarTarget = join('_', $DPKG_NAME, $DPKG_VERSION, $GBE_HOSTNAME) . '.tar.gz';
1011
    my $tarPath = catfile($DPKG_DIR, $tarTarget);
1012
    LogFileOp ('TarZip', $tarPath);
1013
    my @tarArgs;
1014
    push @tarArgs, '-v' if IsVerbose(1);
1015
    my $rv = System ('--NoShell', '--NoExit',$tarProg, @tarArgs, '-czf', $tarPath, '-C', $SRC_ROOT, '.' );
1016
    if ($rv)
1017
    {
1018
        unlink $tarPath;
1019
        unlink $opt_outfile; 
1020
        Error ('Cannot create tarball', "Path:$tarPath");
1021
    }
1022
 
1023
    return 1;
1024
}
1025
 
1026
#-------------------------------------------------------------------------------
1027
# Function        : pkgFindTarBall 
1028
#
1029
# Description     : Used by CreateDpkgArchiveTarBall
1030
#                   File::Find processing function
1031
#                   
1032
#                   This routine is called for each file and directory within the package
1033
#
1034
# Inputs          : As per File::Find 
1035
#
1036
# Returns         : Nothing
1037
#
1038
sub pkgFindTarBall
1039
{
1040
    my $item = $File::Find::name;
1041
    my $base = File::Basename::basename($item);
1042
    my $type;
1043
 
1044
    #
1045
    #   Ignore the top level directory
1046
    #
1047
    return
1048
        if ( $item eq $SRC_ROOT );
1049
 
1050
    #
1051
    #   Determine type of this item
1052
    #       file
1053
    #       link, badlink
1054
    #       dir
1055
    if ( -l $item)
1056
    {
1057
        if (-f $item) {
1058
            $type = 'link';
1059
        }
1060
        else
1061
        {
1062
            # Broken symlink
1063
            #   Remove it from the 'pkg'
1064
            #   Could try other ways of excluding it from the tar, but this is the simplest  
1065
            LogFileOp("Broken SymLink", $item);
1066
            push @bad_symlinks, substr ( $item, 1+length ($SRC_ROOT) );
1067
            $type = 'badlink';
1068
            unlink $item;
1069
            return;
1070
        }
1071
    } elsif ( -f $item) {
1072
        $type = 'file';
1073
    } elsif ( -d $item) {
1074
        $type = 'dir';
1075
    } else {
1076
        Error("Unknown file type. Cannot be packaged");
1077
    }
1078
 
1079
    #
1080
    #   Calculate the target directory name
1081
    #
1082
    my $target = $item;
1083
    $target = $DPKG_DIR . substr ( $item, length ($SRC_ROOT) );
1084
 
1085
    addFile($type, $item, $target);
1086
    LogFileOp('Process',$item);
1087
}
1088
 
1089
#-------------------------------------------------------------------------------
227 dpurdie 1090
# Function        : TestDpkgArchive
1091
#
1092
# Description     : Test the structure of the source achive
1093
#                   Ensure that it has some files
1094
#                   Warn if files are present in the root directory
1095
#
1096
# Inputs          : None
1097
#
1098
# Returns         : Warnings
1099
#
1100
my $test_dir_count = 0;
1101
my $test_file_count = 0;
1102
my @test_root_file = ();
1103
sub TestDpkgArchive
1104
{
1105
    $test_dir_count = 0;
1106
    $test_file_count = 0;
1107
    @test_root_file = ();
1108
 
4003 dpurdie 1109
    if ( $SRC_ROOT ne '' )
1110
    {
1111
        Error("Failed to find dir [$SRC_ROOT]",
1112
              "Check JATS config.") unless ( -d $SRC_ROOT );
1113
 
1114
 
1115
        #
1116
        #   Scan the package counting files and folders
1117
        #
1118
        File::Find::find( \&pkgFind3, $SRC_ROOT );
1119
    }
1120
 
227 dpurdie 1121
    Information ("Package contains:",
1122
                 "Files: $test_file_count",
1123
                 "Dirs: $test_dir_count",
1124
                 );
1125
    #
1126
    #   There shouldn't be any files in the root directory
1127
    #   other than the descpkg and incpkg.
1128
    #
1129
    Warning ("Unexpected files in package root:", @test_root_file)
1130
        if ( @test_root_file  );
4424 dpurdie 1131
 
1132
    Error ("Bad symbolic links found:", @bad_symlinks)
1133
            if ( @bad_symlinks );
1134
 
227 dpurdie 1135
}
1136
 
1137
sub pkgFind3
1138
{
1139
 
1140
    #
1141
    #   Calculate the target directory name
1142
    #
1143
    my $target = $File::Find::dir;
263 dpurdie 1144
    $target = substr ( $target, length ($SRC_ROOT) );
1145
    $target =~ s~^.~~;
227 dpurdie 1146
 
1147
    if ( -d $_ ) {
1148
        $test_dir_count++;
1149
    } else {
1150
        $test_file_count++;
1151
        unless ( $target )
1152
        {
241 dpurdie 1153
            #
1154
            #   Locate files in the package root directory that
1155
            #   are not expected to be there.
1156
            #
263 dpurdie 1157
            unless ((  $_ eq 'descpkg' ) || ( $_ eq 'incpkg' ))
1158
            {
1159
                push @test_root_file, $_;
1160
            }
227 dpurdie 1161
        }
4424 dpurdie 1162
        if (-l $_ && ! -f $_)
1163
        {
1164
            push @bad_symlinks, substr ( $File::Find::name, 1+length ($SRC_ROOT) );
1165
        }
227 dpurdie 1166
    }
1167
}
1168
 
5527 dpurdie 1169
#-------------------------------------------------------------------------------
1170
# Function        : createBuiltFile 
1171
#
1172
# Description     : Create the packages built.xxxx file
1173
#                   Used to track which build machines have contributed to the build 
1174
#
1175
# Inputs          : $targetDir          - Base directory for the file 
1176
#
1177
# Returns         : Full pathname of the generatde file
1178
#
1179
sub createBuiltFile
1180
{
1181
    my ($targetDir) = @_;
1182
 
1183
    #
1184
    #   Mark the archive with the build machine to indicate which parts of
1185
    #   a multi-machine build have been performed
1186
    #
1187
    my $touchfile = catfile( $targetDir, $opt_generic ? 'built.generic' : "built.$GBE_HOSTNAME");
1188
 
1189
    #
1190
    #   Create a string to be appended to the 'built' file
1191
    #   Comma seperated list of (possibly) useful info
1192
    #       Date-Time ( Local and GMT)
1193
    #       machine type, machine name and the user
1194
    #       GBE_ABT value
1195
    #
1196
    #   Having build issues where the file is not seen for a very long time
1197
    #
1198
    my $built_info = localtime() ."," . gmtime() . " GMT,$GBE_MACHTYPE,$GBE_HOSTNAME,$USER,$GBE_ABT";
1199
    LogFileOp("Mark File",$touchfile);
1200
    FileAppend ( $touchfile, $built_info );
1201
 
1202
    return $touchfile;
1203
}
1204
 
1205
 
227 dpurdie 1206
# ---------------------------------------------------------
1207
# ---------------------------------------------------------
1208
# Main
1209
# ---------------------------------------------------------
1210
# ---------------------------------------------------------
1211
 
1212
 
1213
# Initialise our world
1214
#
1215
Init();
4003 dpurdie 1216
CheckDescPkg();
1217
ShowInfo();
4549 dpurdie 1218
unless ($opt_info)
227 dpurdie 1219
{
4549 dpurdie 1220
    unless ( $opt_test )
227 dpurdie 1221
    {
5527 dpurdie 1222
        if ($opt_tarmode)
1223
        {
1224
            Information("Creating dpkg_archive tarball:", $DPKG_DIR);
1225
            CreateDpkgArchiveTarBall();
1226
        }
1227
        else
1228
        {
1229
            Information("Creating dpkg_archive package:", $DPKG_DIR);
1230
            CreateDpkgArchive();
1231
        }
227 dpurdie 1232
    }
4549 dpurdie 1233
    else
1234
    {
1235
        Information("Testing user package.");
1236
        TestDpkgArchive();
1237
    }
227 dpurdie 1238
}
1239
 
1240
# Done
1241
#
1242
Information ("Done.");
1243
exit 0;
1244
 
1245
 
1246
#-------------------------------------------------------------------------------
1247
#   Documentation
1248
#
1249
 
1250
=pod
1251
 
361 dpurdie 1252
=for htmltoc    SYSUTIL::
1253
 
227 dpurdie 1254
=head1 NAME
1255
 
1256
create_dpkg - Create a dpkg_archive entry
1257
 
1258
=head1 SYNOPSIS
1259
 
1260
 jats create_dpkg [options]
1261
 
1262
 Options:
1263
    -help              - Brief help message
1264
    -help -help        - Detailed help message
1265
    -man               - Full documentation
1266
    -quiet             - Suppress progress messages, then warning messages
1267
    -verbose           - Display additional progress messages
4549 dpurdie 1268
    -override          - Deprecated option
1269
    -delete            - Delete any previous version of the package
263 dpurdie 1270
    -[no]merge         - merge with existing version of the package
227 dpurdie 1271
    -archive=name      - Specify archive (cache, local, main, store, sandbox, deploy)
1272
    -pname=name        - Ensure package is named correctly
1273
    -pversion=version  - Ensure package version is correct
1274
    -generic           - Create a built.generic file
5550 dpurdie 1275
    -noBuild           - Create dummy build files
5527 dpurdie 1276
    -[no]tarmode       - Transfer package as tarball
4549 dpurdie 1277
    -[no]md5           - Use MD5 comparison of merged files(enabled)
5527 dpurdie 1278
 
1279
  Debug and Testing:
263 dpurdie 1280
    -[no]test          - Test package. Do not transfer.
4549 dpurdie 1281
    -[no]info          - Display packaging info. Do not transfer.
5527 dpurdie 1282
    -[no]testArchive   - Perform operations within a test archive
227 dpurdie 1283
 
1284
=head1 OPTIONS
1285
 
1286
=over 8
1287
 
1288
=item B<-help>
1289
 
1290
Print a brief help message and exits.
1291
 
1292
=item B<-help -help>
1293
 
1294
Print a detailed help message with an explanation for each option.
1295
 
1296
=item B<-man>
1297
 
1298
Prints the manual page and exits.
1299
 
1300
=item B<-quiet>
1301
 
1302
This option will suppress almost all of the progress messages, except for a single
1303
copy message. It is intended to be used when the program is called from another
1304
script.
1305
 
1306
=item B<-override>
1307
 
4549 dpurdie 1308
If this option has been deprecated. It has no effect.
1309
 
1310
It is still present to preserve backward compatability with the automated 
1311
build system.
1312
 
1313
=item B<-delete>
1314
 
227 dpurdie 1315
If this option is enabled then any previous version of the target package will
4549 dpurdie 1316
be deleted.
227 dpurdie 1317
 
1318
=item B<-merge>
1319
 
1320
If this option is enabled then the package will be merged with any existing
4549 dpurdie 1321
package. This option is used by the auto build tool to assemble multi-machine 
1322
packages in dpkg_archive.
227 dpurdie 1323
 
1324
=item B<-archive=name>
1325
 
1326
This option specifies the destination archive to be used. The following names
1327
are supported:
1328
 
361 dpurdie 1329
=over 8
1330
 
1331
=item cache
1332
 
1333
The location of the target archive will be taken from C<GBE_DPKG_CACHE>.
1334
 
1335
=item local
1336
 
1337
The location of the target archive will be taken from C<GBE_DPKG_LOCAL>.
1338
 
1339
=item main (default)
1340
 
1341
The location of the target archive will be taken from C<GBE_DPKG>. This is the
1342
default target archive.
1343
 
1344
=item store
1345
 
1346
The location of the target archive will be taken from C<GBE_DPKG_STORE>.
1347
 
4688 dpurdie 1348
=item replica
1349
 
1350
The location of the target archive will be taken from C<GBE_DPKG_REPLICA>.
1351
 
361 dpurdie 1352
=item sandbox
1353
 
1354
The location of the target archive will be taken from C<GBE_DPKG_SBOX>.
1355
 
1356
=item deploy
1357
 
1358
The location of the target archive will be taken from C<GBE_DPLY>. This is the
1359
default target archive is a deployment package is detected.
1360
 
1361
=back
1362
 
227 dpurdie 1363
=item B<-pname=name>
1364
 
1365
If this option is provided, the utility will ensure that the package is named
1366
correctly.
1367
 
1368
=item B<-pversion=version>
1369
 
1370
If this option is provided, the utility will ensure that the package version is
1371
that expected.
1372
 
4549 dpurdie 1373
=item B<-generic>
227 dpurdie 1374
 
4549 dpurdie 1375
This option will create a built.generic file, instead of one based on the machine
1376
that actually built the package. This is used by the AutoBuilder toolchain.
227 dpurdie 1377
 
5550 dpurdie 1378
=item B<-noBuild>
1379
 
1380
This option is only used by the build daemons. It is used to create all required 
1381
files to indicate that the build has occured correctly. It will only be used by ANT 
1382
based builds as true JATS builds handle this situation internally.
1383
 
5527 dpurdie 1384
=item B<-[no]tarmode>
1385
 
1386
This option will cause the package to be transferred into the package archive as
1387
a tar ball. Used in the build system to address two issues:
1388
 
1389
=over 4
1390
 
1391
=item 1 
1392
 
1393
Slow speed in copying lots of files from the build machine to the package server.
1394
 
1395
=item 2 
1396
 
1397
Need for cross platform file lock in order to prevent copy collisions.  
1398
 
1399
=back
1400
 
263 dpurdie 1401
=item B<-[no]md5>
1402
 
1403
If package builds are being merged then a validity check is performed using
1404
an MD5 digest over the current and the existing file.
1405
 
1406
By default, it is an error for the user file to differ from the merged file.
1407
 
1408
This option disabled the error. The test is still done and the results are
1409
reported.
1410
 
4549 dpurdie 1411
=item B<-test>
227 dpurdie 1412
 
4549 dpurdie 1413
If this option is enabled the utility will perform initial sanity testing, but
1414
it will not perform the copy.
227 dpurdie 1415
 
4549 dpurdie 1416
=item B<-[no]info>
1417
 
1418
This option will cause the program to display information about the packaging 
1419
process and then exit. 
1420
 
1421
No data will be transferred to the archive.
1422
 
5527 dpurdie 1423
=item B<-[no]testArchive>
1424
 
1425
If this option is enabled then the assembly operation is performed within a test area within
1426
the currently configured dpkg_archive. The test area is a subdirectory 
1427
called C<.dpkg_archive/test_dpkg>
1428
 
1429
This option is intended for testing use only.
1430
 
227 dpurdie 1431
=back
1432
 
1433
=head1 DESCRIPTION
1434
 
1435
This utility program is used to transfer a package that has been built into
1436
dpkg_archive. The package is then available for general consumption.
1437
 
4549 dpurdie 1438
The utility will perform several operations in the transfer process. These incude:
1439
 
1440
=over 4
1441
 
1442
=item * 
1443
 
1444
Create a tag file to indicate the machine that has performed the transfer
1445
 
1446
=item * 
1447
 
1448
Create an XML file of files that have been transferred. This file contains information
1449
used by the build system when it releases the package, including: name, size and MD5SUM.
1450
 
1451
=item *
1452
 
1453
Detect file conflicts when different builds are merged into a single package. Header files are 
1454
allowed to differ in line ending style, but other files must not conflict. The package will not be 
1455
reproducible if file conflicts exist.
1456
 
5527 dpurdie 1457
In 'tarmode' the package merging needs to be done by another utility.
1458
 
4549 dpurdie 1459
=item *
1460
 
1461
Suppress dead symbolic links. A valid symlink will be preserved, but invalid links will be 
1462
removed from the transferred image.
1463
 
1464
=back
1465
 
227 dpurdie 1466
=head2 PACKAGE LOCATION
1467
 
1468
The utility will locate a package by examining the following directores for
1469
the package description file(descpkg).
1470
 
1471
=over 8
1472
 
1473
=item ./build/deploy
1474
 
1475
This format is generated by the deployment builds. The default target archive
1476
will be taken from the environment variable GBE_DPLY.
1477
 
1478
=item ./pkg
1479
 
1480
This format is generated by JATS builds.
1481
 
1482
=item ./build/pkg
1483
 
1484
This format is generated by ANT builds.
1485
 
5527 dpurdie 1486
=item ./pkg/noBuild
1487
 
1488
This format is used internally by this utilty. It will be generated by the build system 
1489
in cases where there is no build to be performs on the current machine.
1490
 
227 dpurdie 1491
=back
1492
 
1493
The program should be run in the same directory as the build control files as
1494
the package subdirectory will be created in that directory.
1495
 
1496
=head1 EXAMPLE
1497
 
1498
=head2 jats create_dpkg
1499
 
1500
This will locate a generated package and install it into the dpkg_archive repository.
1501
 
1502
=cut
1503