source: soft/build_system/build_system/mkcd/tags/V3_0_1_1mdk/mkcd @ 1

Last change on this file since 1 was 1, checked in by fasma, 12 years ago

Initial Import from Mandriva's soft revision 224062 and package revision 45733

File size: 16.1 KB
Line 
1#!/usr/bin/perl
2#
3# to prepare, create and burn iso images
4#
5
6my $VERSION = "3.0.0";
7
8use strict;
9use File::NCopy qw(copy);       
10use Mkcd::Commandline qw(parseCommandLine usage);
11use Mkcd::Tools qw(printTable getTracks du cpal checkcds cleanrpmsrate config compute_md5);
12use Mkcd::Group;
13use Mkcd::Package qw(packageOutOfRpmsrate getLeaves list_hdlist);
14use packdrake;
15use RPM::Header;
16
17#
18# config structure
19#
20# $config{name} = name for the product
21#
22# $config{list} = list data
23#   $config{list}[list number]{name} = list name
24#                             {filelist} = ( file list location 1, file list location 2, ..., file list location n )
25#
26#   $config{list}[list number]{packages}[location i] = (RPMS location i, SRPMS location i)
27#
28#   $config{list}[list number]{done}
29#                             {empty}
30#                             {auto}
31#                             {cd}
32#                             {sources}
33#
34#   $config{list}[list number]{disc} = { cd => { rep => { options }}  }
35#
36# $config{disc} = disc data
37#   $config{disc}[disc number]{size} = size in bytes
38#   $config{disc}[disc number]{serial} = serial number
39#   $config{disc}[disc number]{name} = disc number irl
40#   $config{disc}[disc number]{longname} = disc long name
41#   $config{disc}[disc number]{fastgeneric} = [ generic data 1, generic data 2, ..., generic data n]
42#
43#   $config{disc}[disc number]{function}{list}[function number] = (function name, { data })
44#
45#   $config{disc}[disc number]{function}{data}{dir}{repository identifier} = $config[2][cd number][1][function number]
46#
47#   $config{disc}[disc number]{function}{data}{'installation'} = $config[2][cd number][1][function number]  it should have only one installation by disc, anyway
48#
49#   $config{disc}[disc number]{function}{data}[2]{'advertising'} = $config[2][cd number][1][function number]
50#
51#   $config{disc}[disc number]{steps} = function to execute to build the disc
52#
53#
54# $config other values:
55#
56#    discMax = higher real disc number
57#    configfile = config file use for this session
58#    lists
59#    fast
60#    nodeps
61#    verbose
62#    print
63#    printscript
64#    nolive
65#    noiso
66#    deps
67#    nosrcfit
68#    product
69#    bugzilla
70#    builddir
71#    topdir
72#    discsize
73#    isodir
74#    filetag
75#    log
76#    mkisoopt
77#    tmp
78#
79
80#
81# Availaible functions
82#
83#   see Functions.pm
84#
85
86# old -> new schema
87#
88# config structure
89#
90# $config[0][0] -> $config{name}
91#
92# $config[1] -> $config{list}
93#   $config[1][list number][0] ->  $config{list}[list number]{filelist}
94#
95#   $config[1][list number][1][location i] -> $config{list}[list number]{packages}[location i]
96#
97#   $config[1][list number][2] -> $config{list}[list number]{done}, $config{list}[list number]{empty} $config{list}[list number]{cd}$config{list}[list number]{auto}
98#
99#   $config[1][list number][3] -> $config{list}[list number]{disc}
100#
101# $config[2] -> $config{disc}
102#   $config[2][cd number][0] -> $config{disc}[disc number]{size}, $config{disc}[disc number]{serial}, $config{disc}[disc number]{name}, $config{disc}[disc number]{longname}, $config{disc}[disc number]{fastgeneric}
103#
104#   $config[2][cd number][1][function number] -> $config{disc}[disc number]{function}{list}[function number]
105#
106#   $config[2][cd number][2]{dir}{repository identifier} -> $config{disc}[disc number]{function}{data}{dir}{repository identifier}
107#
108#   $config[2][cd number][2]{'installation'} -> $config{disc}[disc number]{function}{data}{'installation'}
109#
110#   $config[2][cd number][2]{'advertising'} -> $config{disc}[disc number]{function}{data}[2]{'advertising'}
111#
112#   $config[2][cd number][3] -> $config{disc}[disc number]{steps}
113#
114#
115# $config[3] -> $config{discMax}, $config{configfile}
116#
117my $topdir = `pwd`;
118chop $topdir;
119my %config = (
120    lists => [],
121    fast => 0,
122    nodeps => 0,
123    verbose => 0,
124    print => 0,
125    printscript => 0,
126    nolive => 0,
127    noiso => 0,
128    deps => 0,
129    nosrcfit => 0,
130    product => 0,
131    bugzilla => 0,
132    builddir => 0,
133    topdir => $topdir,
134    discsize => 681000000,
135    isodir => 0,
136    filetag => 0,
137    log => 0,
138    mkisoopt => "-r -J -hide-rr-moved -nobak -cache-inodes",
139    tmp => $ENV{TMPDIR} || "$topdir/tmp"
140);
141
142my @params;
143my %FUNCTIONS;
144$config{group} = new Mkcd::Group(\%config);
145my $functions = $config{group}{disc}{functions}{functions};
146my @params = ( 
147    #    [ "one letter option", "long name option", "number of args (-X means Žat least XŽ)", "help text", "function to call", "log info"]
148    [ "","mkcd", 0, "<options>","mkcd Mandrake Linux Disc maker", sub { 1 }, ""],
149    [ "a", "auto", [
150        ["", "auto", -1, "<repository> <extra RPMS directory 1> <extra RPMS directory 2> ... <extra RPMS directory n>","Auto mode configuration", 
151        sub {   my ($tmp,@arg) = @_;
152            $tmp->[0] ||= {};
153            push @$tmp, @arg;
154            1
155        },"Setting auto mode arguments"],
156        ["c", "cd", 1, "<number of discs>","Max number of discs", sub { my ($tmp, $cd) = @_; if ($cd =~ /\d+/) { $tmp->[0]{cd} = $cd } else { return 0 }; 1 },"Setting max number of discs"],
157        ["s", "sources", [
158          [ "", "sources", 0, "<options>", "Sources mode options", 
159            sub {   my ($tmp) = @_;
160                $tmp->[0] ||= {};
161                1
162            },"Setting source mode options"],
163          [ "s", "separate", 0, "","Separate binaries discs from sources discs",sub {my ($tmp) = @_; $tmp->[0]{separate} = 1 },"Setting source mode separate option"]
164        ], "","Create SRPMS discs too", sub { my ($tmp, $opt) = @_; $tmp->[0]{sources} = $opt },"Setting source mode"],
165        ["", "noisolinux", 0, "","Do not use a isolinux boot", sub { my ($tmp) = @_; $tmp->[0]{noisolinux} = 1 },"Setting noisolinux option"]
166], "[options] <repository> <extra RPMS directory 1> <extra RPMS directory 2> ... <extra RPMS directory n>", "Automated mode, build discs from a repository.", \&auto_mode, "Auto mode"],
167    [ "", "bugzilla", 0, "","Use bugzilla as information source.", sub { $config{bugzilla} = 1 }, "Using Bugzilla"],
168    [ "b", "builddir", 1, "<build dir>", "Where live iso image are created (default current dir).",  sub { $config{builddir} = pop @_ }, "Setting the build directory"],
169    [ "", "batch", 2, "<discs list> <batch file>", "batch mode to rebuilt discs from a previous session.",  \&batchMode, "Batch mode"],
170    [ "c", "catto", 1, "<log file>", "Log file.", sub { $config{log} = pop @_; open LOG,">$config{log}" or die "unable to open $config{log}\n"}, "Log file"],
171    [ "", "listrpmsrate", 1,"<rpmsrate file>", "List the package in the rpmsrate file", \&packageOutOfRpmsrate, "Listing rpmsrate file"],
172    [ "d", "depslist-creation", 0 , "", "rebuild the desplist.ordered file before checking the list.", sub { $config{deps}=1 }, "Depslist creation switch"],
173    [ "", "discsize", 1 , "<disc size in bytes>", "Select a custom disc size (default $config{discsize}).", sub { $config{discsize} = pop}, "Custom disc size selection"],
174    [ "f", "fast", 0 , "", "fast mode.", sub { $config{fast} = 1}, "Fast mode"],
175    [ "g", "getdeps", -2, "<depslist.ordered directory> <package 1> <package 2> ... <package n>","Generate the dependencies list of a list of packages.", sub { getdeps(shift,[@_])}, "Generating dependencies list of the packages"],
176    [ "", "getleaves", 1, "<depslist file>", "Getting leaves from a depslist.ordered file",\&getLeaves,"Getting leaves from a depslist.ordered"],
177# FIXME function help should take 0 or one argument, but this is not possible with this structure
178    [ "h", "help", -1, "<path> <to> <the> <function>", "Display help, eg. mkcd -h installation fixed. Type mkcd -h config for configuration files options.", sub { my (@function) = @_; if (@function) { my $key = join '/', @function; usage($key,$FUNCTIONS{$key}) } else { usage("mkcd",\@params)} 1}, ""],
179    [ "", "check", -1, "<dir 1> <dir 2> ... <dir n>", "Check the hdlists, depslist and RPMS consistency.", sub { checkcds(@_)}, "Checking the hdlists, depslist and RPMs consistency"],
180    [ "K", "checkdisc", 2, "<ISO mount point> <md5 file>", "Check the disc.", sub { check_discs(@_)}, "Checking the disc"],
181    [ "i", "isodir", 1, "<iso dir>", "Where ISOs are built (default ./iso/product_name/).",  sub { $config{isodir} = pop @_ }, "Setting the iso directory"],
182    [ "k", "checkcu", -1, "<dir 1> <dir 2> ... <dir n>", "Checking the compssUser.", sub { checkcompssUser([0,@_])}, "Checking the compssUser"],
183    [ "l", "lists", 1 , "","lists of discs taken into account.", sub { $config{lists} = getTracks(pop @_) }, "Using given disc list"],
184    [ "m", "make", 1, "<cds number>", "Build the discs.", \&make , "Building the discs"],
185    [ "", "nodeps", 0, "", "Do not include automatically dependencies of packages", sub { $config{nodeps} = 1 }, "Setting nodeps flag"],
186    [ "", "nolive", 0, "", "Do not create live image of the discs.", sub { $config{nolive} = 1}, "Setting nolive option"],
187    [ "", "noiso", 0, "", "Do not create iso images of the discs.", sub { $config{noiso} = 1}, "Setting noiso option"],
188    [ "", "nosrcfit", 0, "", "Do not stop if sources discs are full", sub { $config{nosrcfit} = 1}, "Setting nosrcfit option"],
189    [ "", "oem", -1, "<root of disc 1> <root of disc 2> ... <root of disc n>", "Build a OEM installation CD based on the given disc", \&oem, "Building oem disc" ],
190    [ "p", "printscript", 1, "<script file>", "Print the script that can be use to rebuild the discs", sub { $config{printscript} = shift}, "Printing script"],
191    [ "", "printdiscsfiles", 1, "<file>", "Print the contains of each disc", sub { $config{print} = shift}, "Printing disc contains"],
192    [ "", "pl", -1, "<hdlist 1> <hdlist 2> ... <hdlist n>", "Do a packdrake -l on the hdlists", sub { list_hdlist(@_) }, "Printing hdlist contents"],
193    [ "s","spec", 1, "<config file>","Configuration file", sub { config(shift,\%config,$functions) } , "Loading configuration file"],
194    [ "t", "topdir", 1, "<top dir>", "Where files are created (default current dir).",  sub { $config{topdir} = pop @_; $config{tmp} = $ENV{TMPDIR} || "$config{$topdir}/tmp" }, "Setting the top directory"],
195    [ "", "update-rpmsrate", -2, "<rpmsrate> <rpms directory 1> <rpms directory 2> ... <rpms directory n>", "Add major to libraries in rpmsrate",  sub { cleanrpmsrate(shift,0,0,@_) }, "Adding major to libraries in rpmsrate"],
196    [ "", "verbose", 0 , "", "Print more messages", sub { $config{verbose} = 1}, "Setting the verbose flag"],
197    [ "v", "version", 0, "", "Print program version",  sub { print {$config{LOG}} "\nmkcd version $VERSION\n"; 1}, ""]
198);
199
200# FIXME this permit to have specific help
201foreach (@params){
202    $FUNCTIONS{"$_->[1]"} = [ $_ ]
203}
204
205$FUNCTIONS{mkcd} = \@params;
206foreach my $k (keys %{$functions}){
207    $FUNCTIONS{$k} = $functions->{$k};
208    foreach (@{$functions->{$k}}){
209        $FUNCTIONS{"$k/$_->[1]"} = ref $_->[2] ? $_->[2] : [ $_ ]
210    }
211    push @{$FUNCTIONS{"config"}} , $functions->{$k}->[0]
212}
213
214local *LOG;
215open LOG,">&STDERR";   
216$config{LOG} = *LOG;
217
218my $todo = parseCommandLine("mkcd",\@ARGV,\@params);
219@ARGV and usage("mkcd",\@params,"@ARGV, too many arguments");
220foreach my $t (@$todo){
221    print LOG "mkcd: $t->[2]\n";
222    &{$t->[0]}(@{$t->[1]}) or print LOG "ERROR: $t->[2]\n";
223}
224
225sub batchMode{
226    my ($cds,$file) = @_;
227    config($file,\%config,$functions);
228    my ($discsFiles,$cd) = readBatchFile($file);
229    my ($lists,$cds) = getDiscsList($cds);
230    my @mkisos;
231    my @size;
232    makeDiscs(0,$lists,$cds,\@size,\@mkisos,$discsFiles);
233    makeDiscs(1,$lists,$cds,\@size,\@mkisos,$discsFiles,$cd);
234}
235
236sub getDiscsList {
237    my ($cds) = @_;
238    my $cds = getTracks($cds);
239    print LOG "getDiscList: discs @$cds\n";
240    my %list;
241    $cds = [grep { ref $config{disc}[$_] and do { $list{$_} = 2; push @{$config{lists}}, $_} or print LOG "WARNING: disc $_ not defined\n" and 0} @$cds];
242    $config{lists} ||= $cds;
243    $config{lists} = [grep { $list{$_} or ref $config{disc}[$_] and $list{$_} = 1 or print LOG "WARNING: disc $_ not defined\n" and 0} @{$config{lists}}];
244    return (\%list,$cds)
245}
246
247sub auto_mode{
248    my ($opt,$repository, @rpms) = @_;
249    $config{nolive} = 1;
250    $config{nosrcfit} = 1;
251    $config{deps} = 1;
252    -d "$repository/Mandrake" or print "ERROR: $repository/Mandrake does not exist\n" and return 0;
253    my $dir = "$repository/Mandrake";
254    local *DIR; opendir DIR, $dir;
255    my $size;
256    foreach (readdir DIR){
257        -d "$dir/$_" or next;
258        /RPMS(\d*)$/ or next;
259        print LOG "auto_mode: adding $dir/$_\n";
260        unshift @rpms, "$dir/$_"
261    }
262    my ($name,$tag);
263    if (-f "$repository/VERSION"){
264        local *A; open A, "$repository/VERSION";
265        <A>;
266        /^Mandrake Linux (.*) \d{8} \d{2}:\d{2}$/;
267        ($name,$tag) = split ' ', $1
268    }
269    $name ||= "Cooker";
270    $config{name} = $name;
271    foreach (keys %$opt) { $config{list}[1]{$_} = $opt->{$_} }
272    $config{list}[1]{auto} = 1;
273    foreach (keys %{$config{list}[1]}) { print LOG "auto_mode: list options $_ -> $config{list}[1]{$_}\n"}
274    foreach (@rpms){
275        #       $size += du($_);
276        push @{$config{list}[1]{packages}}, [$_ , @rpms]
277    }
278    my %cd = ( 1 => 2 );
279    my @cd = ( 1 );
280    #print LOG "Total RPMS $size\n";
281    $config{disc}[1]{size} = $config{discsize};
282    $config{disc}[1]{serial} = "${name}-disc1";
283    $config{disc}[1]{name} = 1;
284    $config{disc}[1]{longname} = "MandrakeLinux $name";
285    my $idx = 1;
286    my %idx;
287    &{$functions->{dir}[0][5]}(1,$idx,"rpms","Mandrake/RPMS");
288    $idx++;
289    &{$functions->{generic}[0][5]}(1,$idx,"rpms",1);
290    $idx++;
291    $idx{installation} = $idx;
292    &{$functions->{installation}[0][5]}(1,$idx);
293    &{$functions->{installation}[5][5]}(1,$idx,"$repository");
294    &{$functions->{installation}[10][5]}(1,$idx,"$tag");
295    &{$functions->{installation}[18][5]}(1,$idx,"1/rpms");
296    $idx++;
297    &{$functions->{boot}[0][5]}(1,$idx);
298    if (-w "$repository/isolinux/isolinux.bin" && !$opt->{noisolinux}){
299        &{$functions->{boot}[1][5]}(1,$idx,{ isolinux => 1 },"isolinux");
300        &{$functions->{boot}[2][5]}(1,$idx,{ bootimg => 1 },"isolinux/isolinux.bin");
301        &{$functions->{boot}[5][5]}(1,$idx,"$repository/isolinux");
302        $idx++;
303        &{$functions->{cp}[0][5]}(1,$idx,"$repository/images","images/");
304    }else{
305        &{$functions->{boot}[2][5]}(1,$idx,{ bootimg => 1, dir => "Boot"},"images/cdrom.img");
306        &{$functions->{boot}[4][5]}(1,$idx,"$repository/images");
307    }
308    if ($opt->{sources}){
309        $config{nosrcfit} = 0;
310        if ($opt->{sources}{separate}){
311            $config{disc}[2]{size} = $config{discsize};
312            $config{disc}[2]{serial} = "${name}-disc2-sources";
313            $config{disc}[2]{name} = 2;
314            $config{disc}[2]{longname} = "MandrakeLinux $name sources";
315            push @cd,2;
316            $cd{2} = 2;
317            &{$functions->{dir}[0][5]}(2,1,"srpms","Mandrake/SRPMS");
318            &{$functions->{generic}[0][5]}(2,2,"srpms",1);
319            &{$functions->{generic}[1][5]}(2,2, { source => 1});
320            &{$functions->{installation}[17][5]}(1,$idx{installation},"2/srpms")
321        }else{
322            $idx++;
323            &{$functions->{dir}[0][5]}(1,$idx,"srpms","Mandrake/SRPMS");
324            $idx++;
325            &{$functions->{generic}[0][5]}(1,$idx,"srpms",1);
326            &{$functions->{generic}[1][5]}(1,$idx, { source => 1});
327            &{$functions->{installation}[17][5]}(1,$idx{installation},"1/srpms")
328        }
329    }else {
330        &{$functions->{installation}[6][5]}(1,$idx)
331    }
332    printTable(\%config);
333    $config{group}->makeWithGroups(\%cd, \@cd);
334    1   
335}
336
337sub make {
338    my ($cds) = @_;
339    $config{group}->makeWithGroups(getDiscsList($cds));
340    1
341}               
342
343sub oem {
344    my (@cds) = @_;
345}
346
347sub check_discs {
348    my ($mntpt,$mdfile) = @_;
349    local *A; open A, "$mdfile";
350    my %ignore;
351    my $sum;
352    while (<A>){
353        chomp;
354        last if ($sum) = /^(.*) - .*$/;
355        my $t = "/$_";
356        $t =~ s/\/\/+/\//g;
357        $ignore{$t} = 1
358    }
359    close A;
360    my $hexdigest = compute_md5([[ "/", $mntpt ]],\%ignore);
361    if ($hexdigest eq $sum){
362        print "\nOK ($hexdigest)\n"
363    }else{
364        print "\nFAILED (computed $hexdigest <> expected $sum)\n";
365        return 0
366    }
367    1
368}
369
370#
371# Changeloh
372#
373# 2002 03 15
374#
375# new sources handling
376#
377# 2002 03 19
378#
379# cdcom are now handled as normal list, so that deps are not forced.
380
381# 2002 03 23
382#
383# change Group.pm getAlone to work with alone group.
384#
385# 2002 03 29
386#
387# fix a bug in Functions.pm for nolive mode and rpmsrate
388#
389# 2002 04 12
390#
391# oem mode
392#
393# 2002 05 02
394#
395# add separate mode for auto sources mode
396#
397# 2002 05 07
398#
399# add check_discs
400#
401# 2002 05 09
402#
403# check_discs, compute_md5, md5_add_tree
404#
405# 2002 05 13
406#
407# fix fentry problem in List.pm that create the "needed spreading" problem
408#
409# 2002 06 01
410#
411# first draft for new needed code
412# new perl-URPM
413#
414# 2002 06 01
415#
416# fix perl-URPM integration
417#
418# 2002 06 15
419#
420# begin new diff mode.
Note: See TracBrowser for help on using the repository browser.