Subversion Repositories DevTools

Rev

Rev 5771 | Rev 6302 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1119 dpurdie 1
########################################################################
2
# Copyright (C) 2007 ERG Limited, All rights reserved
3
#
4
# Module name   : jats.sh
5
# Module type   : Makefile system
6
# Compiler(s)   : n/a
7
# Environment(s): jats
5654 dpurdie 8
# Documents     : MASS-00232 Format of the Linux App Upgrade Manifest File
1119 dpurdie 9
#
10
# Description   : This package extends the JATS toolset at build time
11
#                 It provides additional directives to the JATS makefiles
12
#                 to simplify the directives.
13
#
14
#                 This directive does all its work at 'build' time
15
#                 It uses makefile.pl directives
16
#
17
# Operation     : This package adds the JATS directive ManifestFiles
18
#                 This is used to create linux manifest files
19
#
20
# Syntax        : ManifestFiles (<platforms>, Options+);
21
#                 See the function header for details
22
#
23
#......................................................................#
24
 
25
require 5.6.1;
26
use strict;
27
use warnings;
5649 dpurdie 28
use Digest::file qw(digest_file_hex);
5771 alewis 29
use Digest::file qw(digest_file_base64);
1119 dpurdie 30
 
31
#
32
#   Globals
33
#
34
my @Manifests;                      # Manifest entries
1125 alewis 35
my $Manifest_has_version = 1;       # Create Manifest_xxxx by default
1121 dpurdie 36
my %package_dirs;                   # Package dirs discovered and used
1125 alewis 37
my $pkg_subdir;                     # Alternate packaging
1119 dpurdie 38
 
39
#-------------------------------------------------------------------------------
40
# Function        : BEGIN
41
#
42
# Description     : Setup directive hooks
43
#                   Register a function to be called just before we start to
44
#                   generate makefiles. This will be used to process the data
45
#                   collected in all the ManifestFiles directives
46
#
47
# Inputs          : None
48
#
49
# Returns         : None
50
#
51
BEGIN
52
{
53
    RegisterMakefileGenerate (\&ManifestFiles_Generate);
54
}
55
 
56
#-------------------------------------------------------------------------------
57
# Function        : ManifestFiles
58
#
59
# Description     : Create a ManifestFiles entry
60
#
61
# Inputs          : Platform             - Active Platform Selector
62
#                   Options              - One or more options
63
#                       --Name=Name             - Mandatory
64
#                       --Tier=Name             - Mandatory
65
#                       --Architecture=xxxx     - Default actitecture is the current target
66
#                       --Product=yyyy          - Product Family
67
#                       --Debian=BaseName[,--Prod,--Debug,--Arch=xxxx,--Product=yyyy]
68
#                       --MugPackage=Package[,--Subdir=subdir[,subdir]+]
69
#                       --SrcFile=xxx
1125 alewis 70
#                       --SrcFileNoCopy=xxx
1123 dpurdie 71
#                       --Comment=xxx           - Add comment to Manifst
1125 alewis 72
#                       --NoManifestVersion     - Create unversioned Manifest File
73
#                       --PkgSubdir=xxx         - Specifies packaging subdir
5105 dpurdie 74
#                       --ImportManifest=Package[,--Subdir=subdir,--ReWrite] - Import Manifest from package
5649 dpurdie 75
#                       --Md5                   - Add MD5 checksums to the Manifest File
5767 alewis 76
#                       --Dmf                   - Generate the Device Management Framework
77
#                                                 combined archive ZIP file.
78
#                       --DmfVersion=xxxx       - Generate the Device Management Framework
79
#                                                 combined archive ZIP using a modified
80
#                                                 version number; only for testing!
1119 dpurdie 81
#
82
# Returns         : Nothing
83
#
84
sub ManifestFiles
85
{
86
    my( $platforms, @elements ) = @_;
87
    Debug2( "ManifestFiles($platforms, @elements)" );
88
    return if ( ! ActivePlatform($platforms) );
89
 
90
    my $name;
91
    my $tier;
92
    my @files;
93
    my $mug_dir;
94
    my $default_arch = $::ScmPlatform;
95
    my $default_prod = '';
1129 dpurdie 96
    my $imported_manifest = 0;
5649 dpurdie 97
    my $include_md5 = 0;
5767 alewis 98
    my $generate_dmf = 0;
5771 alewis 99
    my $dmf_version = $::ScmBuildVersionFull;
1119 dpurdie 100
 
101
    #
102
    #   Collect user options
103
    #
104
    foreach ( @elements )
105
    {
106
        if ( m~^--Name=(.+)~ ) {
107
            if ( $name )
108
            {
109
                ReportError ("ManifestFiles:--Name option is only allowed once");
110
                next;
111
            }
112
            $name = $1;
113
 
114
        } elsif ( m~^--Tier=(.+)~ ) {
115
            if ( $tier )
116
            {
117
                ReportError ("ManifestFiles:--Tier option is only allowed once");
118
                next;
119
            }
120
            $tier = $1;
121
 
1123 dpurdie 122
        } elsif ( m~^--Comment=~ ) {
123
            my $cmt = $_;
124
            $cmt =~ s~.+=~~;
125
            $cmt =~ s~\s*\n\s*~\n~g;
126
            push @files, {'cmt' => $cmt };
127
 
1119 dpurdie 128
        } elsif ( m~^--Debian=(.+)~ ) {
1123 dpurdie 129
            push @files, {'file' => LocateDebianFile($1, $default_arch, $default_prod)};
1119 dpurdie 130
 
131
        } elsif ( m~^--SrcFile=(.+)~ ) {
1123 dpurdie 132
            push @files, {'file' => LocatePreReq($1)};
5649 dpurdie 133
 
1125 alewis 134
        } elsif ( m~^--SrcFileNoCopy=(.+)~ ) {
135
            push @files, {'filenocopy' => $1};
5649 dpurdie 136
 
1119 dpurdie 137
        } elsif ( m~^--MugPackage=(.+)~ ) {
138
            if ( $mug_dir )
139
            {
140
                ReportError ("ManifestFiles:--MugPackage option is only allowed once");
141
                next;
5649 dpurdie 142
            }
1119 dpurdie 143
            $mug_dir = LocateMugDir($1);
144
 
145
        } elsif ( m/^--Arch(.*)=(.+)/ ) {
146
            $default_arch = $2;
147
 
148
        } elsif ( m/^--Product=(.+)/ ) {
149
            $default_prod = $1;
150
 
1125 alewis 151
        } elsif ( m/^--NoManifestVersion/i ) {
152
            $Manifest_has_version = 0;
153
 
154
        } elsif ( m/^--PkgSubdir=(.+)/i ) {
155
            if ( $pkg_subdir )
156
            {
1129 dpurdie 157
                ReportError ("ManifestFiles:--PkgSubdir option is only allowed once");
1125 alewis 158
                next;
159
            }
160
            $pkg_subdir = $1;
161
 
1129 dpurdie 162
        } elsif ( m/^--ImportManifest=(.+)/i ) {
5105 dpurdie 163
            my $import_info = ImportManifest($1, $tier, $name);
1129 dpurdie 164
#DebugDumpData("ImportInfo", $import_info );
165
            push @files, {'manifest' => $import_info };
166
 
167
            #
168
            #   Fill in details unless already provided
169
            #
170
            $tier = $import_info->{'tier'} unless ( defined $tier );
171
            $name = $import_info->{'name'} unless ( defined $name );
172
            $imported_manifest = 1;
173
 
5649 dpurdie 174
        } elsif (m/^--Md5/i) {
175
            $include_md5 = 1
176
 
5767 alewis 177
        } elsif (m/^--Dmf/i) {
178
            $generate_dmf = 1
179
 
180
        } elsif ( m/^--DmfVersion=(.+)/ ) {
181
            $generate_dmf = 1;
182
            $dmf_version = $1;
183
 
1119 dpurdie 184
        } else {
185
            ReportError ("ManifestFiles: Unknown option or argument: $_");
186
 
187
        }
188
    }
189
 
190
    #
191
    #   Sanity test the user options
192
    #
193
    ReportError ("ManifestFiles: No name specified")
194
        unless $name;
195
    ReportError ("ManifestFiles: No tier specified")
1129 dpurdie 196
        unless defined ($tier);
1119 dpurdie 197
    ReportError ("ManifestFiles: Cannot mix --Debian/--SrcFile with --MugPackage in one directive")
1129 dpurdie 198
        if ( $mug_dir && (@files || $imported_manifest) );
1119 dpurdie 199
    ReportError ("ManifestFiles: Must specify files to add to Manifest")
1129 dpurdie 200
        unless ( $mug_dir ||  @files || $imported_manifest);
1119 dpurdie 201
    ErrorDoExit();
202
 
203
    #
204
    #   Save information for processing at the end of the parsing phase
205
    #   Data collected from ALL the ManifestFiles directives will be collected
206
    #   and processed into one Manifest file
207
    #
208
    my %data;
209
    $data{tier} = $tier;
210
    $data{name} = $name;
211
    $data{files} = \@files;
212
    $data{mugdir} = $mug_dir;
1125 alewis 213
    $data{pkgsubdir} = $pkg_subdir;
5649 dpurdie 214
    $data{md5} = $include_md5;
5767 alewis 215
    $data{dmf} = $generate_dmf;
216
    $data{arch} = $default_arch;
217
    $data{dmf_version} = $dmf_version;
218
 
1129 dpurdie 219
#DebugDumpData("DirectiveData", \%data );
1119 dpurdie 220
 
221
    push @Manifests, \%data;
222
    return;
223
 
224
    #-------------------------------------------------------------------------------
225
    # Function        : LocateDebianFile
226
    #
227
    # Description     : Locate a debian file
228
    #                   Internal Function
229
    #
230
    #                   Scan packages for the Debian package specified
231
    #                   The user provides the base name of the package
232
    #                   A Debian Package name has several fields
233
    #                   These are:
234
    #                       1) Base Name - Provided by the user
235
    #                       2) Version - Version will be wildcarded
236
    #                       3) Architecture - Wildcarded. Uses bin/arch directory
5649 dpurdie 237
    #
1119 dpurdie 238
    #                   Expect to find Debian Packages in the bin/PLATFORM subdir
239
    #
240
    # Inputs          : Debian base name, complete with suboptions
241
    #
242
    # Returns         : Full path of the file
243
    #
244
    sub LocateDebianFile
245
    {
246
        my ($arg, $arch, $product) = @_;
247
        Verbose("LocateDebianFile: Processing: $arg");
248
 
249
        my @type = qw( P D );
250
        my @debian_file_path;
5649 dpurdie 251
 
1119 dpurdie 252
        #
253
        #   Extract sub-options
254
        #       --Prod[uction]
255
        #       --Debug
256
        #       --Arch[itecture]=yyy
257
        #
258
        my ($base_name, @opts) = split( ',', $arg );
259
        foreach ( @opts )
260
        {
261
            if ( m/^--Arch(.*)=(.+)/ ) {
262
                $arch=$2;
263
            } elsif ( m/^--Product=(.+)/ ) {
264
                $product=$1;
265
            } elsif ( m/^--Prod/ ) {
266
                @type = 'P';
267
            } elsif ( m/^--Debug/ ) {
268
                @type = 'D';
269
            }
270
        }
271
 
272
        #
273
        #   Create a list of products
274
        #   ie: PRODUCT_ARCH
275
        #
276
        my @products;
277
        push @products, $product . '_' . $arch if ( $product );
278
        push @products, $arch;
279
 
280
        #
281
        #   Scan all packages for the specified debian package
282
        #
283
        foreach my $package_dir ( getPackagePaths ('--All') )
284
        {
285
            foreach my $type ( @type )
286
            {
287
                foreach my $prd ( @products )
288
                {
289
                    foreach my $joiner ( qw(/ .) )
290
                    {
291
                        my $dir = "$package_dir/bin$joiner$prd$type";
292
                        Verbose("ManifestFiles: Search in $dir");
293
                        next unless ( -d $dir );
294
                        my @files = glob ( "$dir/${base_name}_*.deb" );
295
                        next unless ( @files );
296
                        push @debian_file_path, @files;
1121 dpurdie 297
                        $package_dirs{$package_dir}{used} = 1;
1119 dpurdie 298
                    }
299
                }
300
            }
5873 acammell 301
            foreach my $type ( @type )
302
            {
303
                foreach my $prd ( @products )
304
                {
305
                    my $dir = "$package_dir";
306
                    Verbose("ManifestFiles: Search in $dir");
307
                    next unless ( -d $dir );
308
                    my @files = glob ( "$dir/${base_name}_*_${prd}_${type}.deb" );
309
                    next unless ( @files );
310
                    push @debian_file_path, @files;
311
                    $package_dirs{$package_dir}{used} = 1;
312
                }
313
            }
1119 dpurdie 314
        }
315
 
5752 dpurdie 316
        ReportError ("Required Debian package not found: $base_name") unless @debian_file_path;
1121 dpurdie 317
        ReportError ("Multiple matching Debian Packages located: $base_name", @debian_file_path ) if ( $#debian_file_path > 0 );
1119 dpurdie 318
        return $debian_file_path[0];
319
    }
320
 
321
    #-------------------------------------------------------------------------------
322
    # Function        : LocateMugDir
323
    #
324
    # Description     : Locate the directory containing the mugfiles
325
    #                   Internal Function
326
    #
327
    # Inputs          : Mufile package, with embedded options
328
    #
329
    # Returns         : Full path
330
    #
331
    sub LocateMugDir
332
    {
333
        my ($mug_package) = @_;
334
 
335
        #
336
        #   Locate the mugfile subdir
337
        #
338
        my $package_name = $mug_package;
339
        my @dirs = 'mug';
340
        my $mug_dir;
341
 
342
        #
343
        #   Extract sub options
344
        #       --Subdir=xxxx,yyyy,zzzz
345
        #
346
        if ( $package_name =~ m/(.*?),--Subdir=(.*)/ )
347
        {
348
            $package_name = $1;
349
            @dirs = split( ',', $2 );
350
        }
351
 
352
        my $package = GetPackageEntry( $package_name );
353
        unless ( $package )
354
        {
355
            ReportError ("ManifestFiles: Package not known to build: $package_name");
356
            return undef;
357
        }
358
 
359
        foreach my $subdir ( @dirs )
360
        {
361
            my $dir = "$package->{'ROOT'}/$subdir";
362
            if ( -d $dir )
363
            {
364
                Warning ("Multiple Mugfile directories located. Only the first will be used",
365
                         "Ignoring: $subdir" )if ( $mug_dir );
366
                $mug_dir = $dir;
367
            }
368
        }
369
        ReportError ("Mugfile directory not found in package: $package_name")
370
            unless $mug_dir;
371
 
372
        return $mug_dir;
373
    }
1129 dpurdie 374
 
375
    #-------------------------------------------------------------------------------
376
    # Function        : ImportManifest
377
    #
378
    # Description     : Import an existing manifest
379
    #
5105 dpurdie 380
    # Inputs          : Args    - PackageName[,Subdir=name,--ReWrite]
381
    #                   tier    - May be null
382
    #                   name    - May be null
1129 dpurdie 383
    #
384
    # Returns         : A hash of data to be used later
385
    #
386
    sub ImportManifest
387
    {
5105 dpurdie 388
        my ($args, $tier, $name) = @_;
1129 dpurdie 389
        my @file_contents;
390
        my @file_list;
391
 
392
        #
393
        #   Locate the mugfile subdir
394
        #
395
        my $package_name = $args;
396
        my @dirs = 'mug';
397
        my $pkg_dir;
398
        my $pkg_root;
399
        my $manifest;
400
        my $first_tier;
401
        my $first_name;
5105 dpurdie 402
        my $rewrite;
1129 dpurdie 403
 
404
        #
405
        #   Extract sub options
406
        #       --Subdir=xxxx,yyyy,zzzz
5105 dpurdie 407
        #       --ReWrite
1129 dpurdie 408
        #
5105 dpurdie 409
        if ( $package_name =~ m/(.*?)(,.*)/ )
1129 dpurdie 410
        {
411
            $package_name = $1;
5105 dpurdie 412
            my @subargs = split(',--', $2);
413
            foreach ( @subargs)
414
            {
415
                next unless (length($_) > 0);
416
                if (m~^Subdir=(.*)~i){
417
                    @dirs = split( ',', $1 );
418
 
419
                } elsif (m~^ReWrite~i) {
420
                    $rewrite = 1;
421
 
422
                } else {
423
                    ReportError("ManifestFiles: Unknown suboption to ImportManifest:" . $_);
424
                }
425
            }
1129 dpurdie 426
        }
427
 
428
        my $package = GetPackageEntry( $package_name );
429
        unless ( $package )
430
        {
431
            ReportError ("ManifestFiles: Package not known to build: $package_name");
432
            return undef;
433
        }
434
 
5105 dpurdie 435
        if (defined ($rewrite) && ( !defined($tier) || !defined($name)))
436
        {
437
            ReportError ("ManifestFiles: ImportManifest. --ReWrite cannot be used unless tier and name are specified");
438
            return undef;
439
        }
440
 
1129 dpurdie 441
        foreach my $subdir ( @dirs )
442
        {
443
            my $dir = "$package->{'ROOT'}/$subdir";
444
            my $root = $package->{'ROOT'};
445
            if ( -d $dir )
446
            {
447
                Warning ("Multiple Package directories located. Only the first will be used",
448
                         "Ignoring: $subdir" )if ( $pkg_dir );
449
                $pkg_dir = $dir;
450
                $pkg_root = $root;
451
            }
452
        }
453
 
5105 dpurdie 454
        unless ($pkg_dir)
455
        {
456
            ReportError ("Package directory not found in package: $package_name");
457
            return undef;
458
        }
459
 
1129 dpurdie 460
        #
461
        #   Determine Manifest File name
462
        #
463
        foreach my $file ( glob ($pkg_dir . '/Manifest*' ) )
464
        {
465
                next unless ( -f $file );
466
                Warning ("Multiple Manifest Files find. Only the first will be used",
467
                         "Using: $manifest",
468
                         "Ignoring: $file" ) if ( $manifest );
469
                $manifest = $file;
470
        }
471
 
5105 dpurdie 472
        unless ($manifest)
473
        {
474
            ReportError ("ImportManifest. No Manifest found: $package_name");
475
            return undef;
476
        }
1129 dpurdie 477
 
5105 dpurdie 478
 
1129 dpurdie 479
        #
480
        #
5649 dpurdie 481
        #
1129 dpurdie 482
        open (MF, '<', $manifest ) || Error ("Cannot open the Manifest file: $manifest", $!);
483
        while ( <MF> )
484
        {
1131 dpurdie 485
            #
5711 kspencer 486
            #   Clean trailing whitespace ( line-feed and new lines )
1131 dpurdie 487
            #   Comment out [Version] data
488
            #
1129 dpurdie 489
            s~\s+$~~;
1131 dpurdie 490
            s~(\s*\[Version])~#$1~;
1129 dpurdie 491
 
492
            #
493
            #   Part lines and determine files
494
            #
495
            next unless ( $_ );
496
            next if ( m~\s*#~ );
497
            next if ( m~\s*\[~ );
498
            my( $aname, $atier, $afile) = split(/\s*\,\s*/, $_);
499
#            print "---------- $_\n";
500
#            print "T: $atier, N:$aname, F:$afile\n";
501
            push @file_list, $afile;
502
 
503
            #
5105 dpurdie 504
            #   Rewrite the name and tier
1129 dpurdie 505
            #
5105 dpurdie 506
            if ($rewrite)
507
            {
508
                $_ = join(',', $name, $tier, $afile);
509
                $first_tier = $tier;
510
                $first_name = $name;
511
            }
512
            else
513
            {
514
                #
515
                #   Capture first tier and name
516
                #
517
                $first_tier = $atier unless ( defined $first_tier );
518
                $first_name = $aname unless ( defined $first_name );
519
            }
1129 dpurdie 520
        }
5105 dpurdie 521
        continue
522
        {
523
            push @file_contents, $_;
524
        }
1129 dpurdie 525
        close MF;
526
 
527
        #
528
        #   Create a hash of data that describes the manifest that has
529
        #   just been read in.
530
        #
531
        $package_dirs{$pkg_root}{used} = 1;
532
        $manifest =~ s~.*/~~;
533
        return { 'contents' => \@file_contents,
534
                  'files' => \@file_list,
535
                  'file_base' => $pkg_dir,
536
                  'manifest' => $manifest,
537
                  'pkg_dir' => $pkg_root,
538
                  'tier' => $first_tier,
539
                  'name' => $first_name,
5105 dpurdie 540
                  'rewrite' => $rewrite,
1129 dpurdie 541
                };
542
    }
1119 dpurdie 543
}
544
 
545
#-------------------------------------------------------------------------------
546
# Function        : ManifestFiles_Generate
547
#
548
# Description     : Internal Function
549
#                   Process all the collected data and create directives
550
#                   for the creation of the manifest
551
#
552
#                   This function will be called, just before the Makefile
553
#                   is created. The function will:
554
#                       1) Create the Manifest File
555
#                       2) Package the Manifest File
556
#                       3) Package the manifest file contents
557
#
558
#                   using (mostly) normal makefile.pl directives.
559
#
560
# Inputs          : None
561
#
562
# Returns         : Nothing
563
#
564
sub ManifestFiles_Generate
565
{
566
    Debug ("ManifestFiles_Generate");
567
    Message ("Generating Manifest File");
1123 dpurdie 568
 
569
    #
570
    #   Need at least one Manifest Entry
571
    #
572
    return unless ( @Manifests );
1119 dpurdie 573
#DebugDumpData ( "Manifests", \@Manifests );
574
 
575
    #
1125 alewis 576
    #   Determine the target packaging directory
577
    #   Default is .../mug
578
    #
579
    my $pkgdir = 'mug';
1129 dpurdie 580
    if ( exists $Manifests[0]->{pkgsubdir} && defined $Manifests[0]->{pkgsubdir} )
1125 alewis 581
    {
582
        my $subdir = $Manifests[0]->{pkgsubdir};
583
        $pkgdir .= '/' . $subdir;
584
        $pkgdir =~ s~^mug/mug~mug~;
585
    }
586
 
587
    #
1119 dpurdie 588
    #   Create the Manifest File as we process the lists
1125 alewis 589
    #   Place this in the 'lib' directory:
1119 dpurdie 590
    #       - So that it will be deleted on clobber
1123 dpurdie 591
    #       - So that it can be placed in a target-specific subdir
1125 alewis 592
    #       - So that we can have one per makefile.pl
1119 dpurdie 593
    #
594
    Error ("ManifestFiles: Needs local directory specified in build.pl") unless ( $::ScmLocal );
595
 
1125 alewis 596
    my $manifest_dir = "$::ScmPlatform.LIB";
1119 dpurdie 597
    System( "$::GBE_BIN/mkdir -p $manifest_dir" );
598
 
1125 alewis 599
    my $manifest_file = $manifest_dir . '/Manifest';
600
    $manifest_file .= '_' . $::ScmBuildVersion if ( $Manifest_has_version );
601
    ToolsetGenerate( $manifest_file );
1119 dpurdie 602
    Verbose ("ManifestFiles_Generate: File: $manifest_file");
5649 dpurdie 603
 
1125 alewis 604
    PackageFile ('*', $manifest_file, '--Subdir=' . $pkgdir, '--Strip' );
1119 dpurdie 605
 
606
    open (MF, '>', $manifest_file ) || Error ("Cannot create the Manifest file: $manifest_file");
607
 
5711 kspencer 608
    binmode (MF);
5767 alewis 609
 
1119 dpurdie 610
    print_mf ("# PackageName: $::ScmBuildPackage");
611
    print_mf ("# PackageVersion: $::ScmBuildVersion");
612
    print_mf ("# BuildDate: $::CurrentTime");
613
    print_mf ("#");
614
    print_mf ("[Version],$::ScmBuildVersion");
615
    print_mf ("#");
616
 
617
    #
1125 alewis 618
    #   Process each tier in the order presented in the source file
1119 dpurdie 619
    #
1123 dpurdie 620
    my $last_was_comment = 0;
1119 dpurdie 621
    foreach my $entry ( @Manifests )
622
    {
1127 alewis 623
    #print_mf ("#");
1119 dpurdie 624
 
625
#DebugDumpData ( "Manifest Entry", $entry );
626
 
627
        my $tier = $entry->{tier};
628
        my $name = $entry->{name};
5649 dpurdie 629
        my $include_md5 = $entry->{md5};
1119 dpurdie 630
 
5767 alewis 631
        if ( $entry->{dmf} )
632
        {
633
        	DmfGenerate($entry);
634
        }
635
 
1119 dpurdie 636
        #
637
        #   Insert all the files that have been specified
638
        #   The user specified order is preserved
639
        #
1123 dpurdie 640
        #   Entries may be either a file or a comment
641
        #   Comments: Merge multiple comments and create blocks
642
        #
643
        #
1119 dpurdie 644
        my @files = @{ $entry->{files} };
1123 dpurdie 645
        foreach my $fentry ( @files )
1119 dpurdie 646
        {
1123 dpurdie 647
            if ( my $cmt = $fentry->{'cmt'} )
648
            {
649
                print_mf ('') unless ( $last_was_comment ) ;
650
                print_mf ( map (('# ' . $_) , split ("\n", $cmt) ));
651
                $last_was_comment = 1;
652
                next;
653
            }
654
 
655
            print_mf ('#') if ( $last_was_comment );
656
            if ( my $file = $fentry->{'file'} )
657
            {
658
                my $base_file = StripDir( $file );
5649 dpurdie 659
                if ($include_md5) {
660
                    my $md5 = digest_file_hex($file, 'MD5');
5654 dpurdie 661
                    print_mf ('--NoCheckLineWidth', "$name,$tier,$base_file,MD5=$md5");
5649 dpurdie 662
                } else {
663
                    print_mf ("$name,$tier,$base_file");
664
                }
1125 alewis 665
                PackageFile ('*', $file, '--Subdir=' . $pkgdir, '--Strip' );
1123 dpurdie 666
                $last_was_comment = 0;
667
            }
1125 alewis 668
 
669
            if ( my $file = $fentry->{'filenocopy'} )
670
            {
671
                print_mf ("$name,$tier,$file");
672
                $last_was_comment = 0;
673
            }
1129 dpurdie 674
 
675
            if ( my $emf = $fentry->{'manifest'} )
676
            {
677
                $last_was_comment = 0;
678
                #
679
                #   Insert the entire manifest
680
                #   Items are:
681
                #        contents
682
                #        files
683
                #        file_base
684
                #        manifest
685
                #
686
#DebugDumpData ( "Embedded Manifest Entry", $emf );
687
                print_mf ( '## Included Manifest: ' .  $emf->{'manifest'}  );
688
                print_mf ($_) foreach  ( @{$emf->{'contents'}} );
689
                PackageFile ('*', $emf->{'file_base'}. '/' . $_, '--Subdir=' . $pkgdir, '--Strip' )foreach  ( @{$emf->{'files'}});;
690
                print_mf ( '## End Included Manifest' );
691
            }
1119 dpurdie 692
        }
693
 
694
        #
695
        #   Expand out the entire MUG directory
696
        #   All .mug files in the MUG directory will be added to the manifest
697
        #   The assumption is that the MUG directory has been created by
698
        #   something that knows what its doing
699
        #
700
        if ( my $mugdir = $entry->{mugdir} )
701
        {
702
            foreach my $file ( glob ($mugdir . '/*.mug' ) )
703
            {
704
                next unless ( -f $file );
705
                my $base_file = StripDir($file);
5654 dpurdie 706
                if ($include_md5) {
707
                    my $md5 = digest_file_hex($file, 'MD5');
708
                    print_mf ('--NoCheckLineWidth', "$name,$tier,$base_file,MD5=$md5");
709
                } else {
710
                    print_mf ("$name,$tier,$base_file");
711
                }
1119 dpurdie 712
                PackageFile ('*', $file, '--Subdir=mug', '--Strip' );
713
            }
714
        }
715
    }
716
 
717
    #
718
    #   Complete the creation of the Manifest File
719
    #
720
    print_mf ("#");
721
    print_mf ("# End of File");
722
    close MF;
723
    ErrorDoExit();
1121 dpurdie 724
 
725
    #
726
    #   Sanity test of packages that did not provide a debian file
727
    #   Just a hint that something may have been missed
728
    #
729
    my @not_used_packages;
730
    foreach my $package_dir ( getPackagePaths ('--All') )
731
    {
732
        next if ( $package_dir =~ m~/manifest-tool/~ );
733
        unless ( exists $package_dirs{$package_dir}{used} )
734
        {
735
            push @not_used_packages, $package_dir;
736
        }
737
    }
738
    if ( @not_used_packages )
739
    {
740
        Warning ("Packages that did not contribute packages to the manifest:",
741
                  @not_used_packages );
742
    }
743
 
1119 dpurdie 744
    return;
745
 
746
    #-------------------------------------------------------------------------------
747
    # Function        : print_mf
748
    #
749
    # Description     : Internal Function
750
    #                   Print one line to the Manifest File
751
    #                   Checks the length of the line being created
752
    #
753
    # Inputs          : $line
754
    #
5649 dpurdie 755
    # Returns         :
1119 dpurdie 756
    #
757
 
758
    sub print_mf
759
    {
5649 dpurdie 760
        my $check_line_width = 1;
761
 
762
        if ($_[0] eq '--NoCheckLineWidth')
763
        {
764
            shift @_;
765
            $check_line_width = 0;
766
        }
767
 
1119 dpurdie 768
        foreach  ( @_ )
769
        {
770
            ReportError ( "Manifest line too long",
5649 dpurdie 771
                    "Line: $_" ) if ( $check_line_width && length ($_) > 79);
1119 dpurdie 772
            print MF $_ . "\n";
773
        }
774
    }
775
}
776
 
5767 alewis 777
# Bring in the DMF build requirements.
778
my $directory;
779
BEGIN {
780
    use File::Spec::Functions qw(rel2abs);
781
    use File::Basename qw(dirname);
782
 
783
    my $path = rel2abs( __FILE__ );
784
    $directory = dirname( $path );
785
}
786
use lib $directory;
787
 
788
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
789
use JSON;
790
 
791
#-------------------------------------------------------------------------------
792
# Function        : DmfGenerate
793
#
794
# Description     : Import an existing manifest
795
#
796
# Inputs          : entry   - The manifest that is being processed.
797
#
798
# Returns         : Nothing
799
#
800
sub DmfGenerate
801
{
802
    my ($entry) = @_;
803
 
804
    # Get the generation time.
805
    my $gen_time = time();
806
 
807
    my $work_dir = "$::ScmPlatform.BIN/";
808
    System( "$::GBE_BIN/mkdir -p $work_dir" );
809
 
810
    my $name = $entry->{name};
811
    my $version = $entry->{dmf_version};
812
 
813
    # Configure base manifest information.
814
    my %manifest;
5771 alewis 815
    $manifest{'mugsetId'} = $name . '_' . $version;
5767 alewis 816
    $manifest{'name'} = $name;
817
    $manifest{'version'} = $version;
5771 alewis 818
    $manifest{'packageName'} = $::ScmBuildPackage;
819
    $manifest{'packageVersion'} = $::ScmBuildVersionFull;
5767 alewis 820
    $manifest{'datetime'} = localtime($gen_time);
821
    $gen_time *= 1000;  # Make to milliseconds
822
    $manifest{'timestamp'} = $gen_time;
823
    $manifest{'tier'} = $entry->{tier};
824
 
825
    # Process each file.
826
    my @files = @{ $entry->{files} };
827
    my $zip = Archive::Zip->new();
828
    my $i = 0;
829
    foreach my $fentry ( @files )
830
    {
831
        if ( my $file = $fentry->{'file'} )
832
        {
833
        	my $order = $i + 1;
834
            my $base_file = StripDir( $file );
835
            my $publish_file = $name . '_' . $version . '_' . $order . '.aup';
836
            my $aup_file = $work_dir . $publish_file;
837
 
838
            GenerateCesFile($file, $aup_file, 0x3, $gen_time, $publish_file);
839
 
840
            my $file_member = $zip->addFile( $aup_file, $publish_file );
841
 
842
            $manifest{'tasks'}[$i]{'order'} = 1 * $order;
843
            $manifest{'tasks'}[$i]{'filename'} = $base_file;
844
            $manifest{'tasks'}[$i]{'download'} = $publish_file;
5771 alewis 845
            $manifest{'tasks'}[$i]{'sha256'} = digest_file_base64($file, 'SHA-256');
846
            $manifest{'tasks'}[$i]{'size'} = -s $file;
847
 
5767 alewis 848
            if ($base_file =~ /\.sh$/)
849
            {
850
                $manifest{'tasks'}[$i]{'action'} = 'exec-shell';
851
            }
852
            elsif ($base_file =~ /\.deb$/)
853
            {
854
                $manifest{'tasks'}[$i]{'action'} = 'dpkg-install';
5771 alewis 855
 
856
                my ($pkg_name, $pkg_version, $pkg_arch) = ($base_file =~ /([^_]*)_([^_]*)_(.*)/);
857
                $manifest{'tasks'}[$i]{'arch'} = $pkg_arch;
858
                $manifest{'tasks'}[$i]{'name'} = $pkg_name;
859
                $manifest{'tasks'}[$i]{'version'} = $pkg_version;
5767 alewis 860
            }
861
            else
862
            {
863
                ReportError ("Manifest entry $base_file does not have a supported DMF install action");
864
            }
865
 
866
            $i = $i + 1;
867
        }
868
    }
869
 
870
    # Encode and commit the JSON.
871
    my $json_encoder = JSON->new->allow_nonref;
872
    my $json = $json_encoder->pretty->encode( \%manifest );
873
 
874
    my $manifest_filename = $name . '_' . $version;
875
    my $aum_filename = $manifest_filename . '_0.aum';
876
    my $manifest_file = $work_dir . $manifest_filename . '.json';
877
    my $aum_file = $work_dir . $aum_filename;
878
 
879
    # Save our manifest.
880
    open (J, '>', $manifest_file ) || Error ("Cannot create the DMF Manifest file");
881
    binmode (J);
882
    print J $json;
883
 
884
    close J;
885
 
886
    GenerateCesFile($manifest_file, $aum_file, 0x2, $gen_time, $aum_filename);
887
 
888
    $zip->addFile($aum_file, $aum_filename);
889
 
890
    my $zip_filename = $work_dir . $name . '_' . $version . '.zip';
891
    if ( $zip->writeToFileNamed($zip_filename) != AZ_OK )
892
    {
893
        ReportError("DMF ZIP file creation failed");
894
    }
895
    PackageFile('*', $zip_filename, '--Strip');
896
    PackageFile('*', $manifest_file, '--Strip');
897
 
898
}
899
 
900
#-------------------------------------------------------------------------------
901
# Function        : DmfGenerate
902
#
903
# Description     : Import an existing manifest
904
#
905
# Inputs          : src_file     - The input file.
906
#                   dst_file     - The output CES file.
907
#                   content_type - The content type to report.
908
#                   gen_time     - The generation time for the file.
909
#                   filename     - The filename to embed in the CES file.
910
#
911
#
912
# Returns         : Nothing
913
#
914
sub GenerateCesFile
915
{
916
    my ($src_file, $dst_file, $content_type, $gen_time, $filename) = @_;
917
 
918
    open (INF, '<', $src_file ) || Error ("Cannot open file $src_file for reading");
919
    binmode (INF);
920
 
921
    open (OUTF, '>', $dst_file ) || Error ("Cannot open file $dst_file for writing");
922
    binmode (OUTF);
923
 
924
    my $signing_key_name = "";
925
    my $signature_size = 0;
926
    my $format_version = 0xCE500000;
927
    my $compression_method = 0;
928
    my $encryption_method = 0;
929
    my $kek_name = "";
930
    my $encryption_key_size = 0;
931
    my $filename_size = length($filename);
932
 
933
    print OUTF pack("Z32", $signing_key_name);
934
    print OUTF pack("n", $signature_size);
935
    print OUTF pack("N", $format_version);
936
    print OUTF pack("N", $content_type);
937
    print OUTF pack("Q>", $gen_time);
938
    print OUTF pack("N", $compression_method);
939
    print OUTF pack("N", $encryption_method);
940
    print OUTF pack("Z32", $kek_name);
941
    print OUTF pack("n", $encryption_key_size);
942
    print OUTF pack("n", $filename_size);
943
    # Encryption key HERE
944
    print OUTF pack("A$filename_size", $filename);
945
 
946
    my $buf;
947
    while (read(INF,$buf,65536))
948
    {
949
        print OUTF $buf;
950
    }
951
    print OUTF $buf;
952
    close INF;
953
 
954
    # Signature HERE
955
 
956
    # Finish with file.
957
    close OUTF;
958
}
959
 
1119 dpurdie 960
1;