Add OpenAFS to the dependencies of remote-fs.
[openafs.git] / src / packaging / RedHat / mockbuild.pl
1 #!/usr/bin/perl
2 # mockbuild - mass RPM build driver for use with mock and many kernel-devel
3 #             RPMs
4 # from Simon Wilkinson for OpenAFS
5 # for "modern" yum, use "showdupesfromrepos=1" in all cfg files in /etc/mock
6
7 use strict;
8 use warnings;
9
10 use Getopt::Long;
11 use File::Path;
12 use IO::Dir;
13 use File::Temp qw/ tempfile tempdir /;
14
15 my $suser="nsu";
16 my $rootbase="/var/lib/mock/";
17 my $resultbase="/tmp/result/";
18 my $stashbase="/disk/scratch/repository/";
19 my $mockcommand = "/usr/bin/mock";
20 my $resultfile;
21 my $buildall = 0;
22 my $ignorerelease = 1;
23 my @newrpms;
24
25 sub findKernels {
26   my ($root, $platform, $uname, @modules) = @_;
27
28   my ($fh, $tmpconf) = tempfile( "yum.confXXXX", DIR => "/tmp");
29   open(OLDCONF, "$root/etc/yum.conf");
30   while(<OLDCONF>) {
31       $_ =~ s#/var/cache/yum#/var/cache/mock/${platform}/yum_cache#;
32       print $fh $_;
33   }
34   close(OLDCONF);
35   my $archv = "";
36   open(PLATCONF, "/etc/mock/${platform}.cfg");
37   while (<PLATCONF>) {
38       if ($_ =~ "legal_host_arches") {
39           $_ =~ s/ //g;
40           $_ =~ /\(([\S]*)\)/;
41           $_ = $1;
42           if ($platform =~ "i386") {
43               $_ =~ s/\'x86_64\'//;
44               $_ =~ s/\,\,/\,/;
45               $_ =~ s/\,\$//;
46           }
47           if ($_ ne "") {
48               $archv="--archlist=$_";
49           }
50       }
51   }
52   close(PLATCONF);
53   my $modlist = join(" ", @modules);
54   my @kernels;
55   if ($uname) {
56     @kernels = `repoquery $archv --whatprovides kernel-devel-uname-r --qf "%{name}.%{arch} %{version}-%{release}" -c $tmpconf`;
57   } else {
58     @kernels = `repoquery $archv --show-duplicates --whatprovides $modlist --qf "%{name}.%{arch} %{version}-%{release}" -c $tmpconf`;
59   }
60   unlink $tmpconf;
61
62   return @kernels;
63 }
64
65
66 my %platconf = ( "centos-4-i386" => { osver => "el4",
67                                      kmod => '1',
68                                      basearch => 'i386',
69                                      updaterepo => 'update',
70                                      results => 'rhel4/i386' },
71                  "centos-4-x86_64" => { osver => "el4",
72                                        kmod => '1',
73                                        basearch => 'x86_64',
74                                        updaterepo => 'update',
75                                        results => "rhel4/x86_64" },
76                  "centos-5-i386" => { osver => "el5", 
77                                       kmod => '1', 
78                                       basearch => 'i386',
79                                       updaterepo => 'update',
80                                       results => "rhel5/i386" },
81                  "centos-5-x86_64" => { osver => "el5",
82                                         kmod => '1',
83                                         basearch => 'x86_64',
84                                         updaterepo => 'update',
85                                         results => "rhel5/x86_64" },
86                  "centos-6-i386" => { osver => "el6", 
87                                       kmod => '1', 
88                                       basearch => 'i686',
89                                       updaterepo => 'update',
90                                       results => "rhel6/i686" },
91                  "centos-6-x86_64" => { osver => "el6",
92                                         kmod => '1',
93                                         basearch => 'x86_64',
94                                         updaterepo => 'update',
95                                         results => "rhel6/x86_64" },
96                  "epel-4-i386" => { osver => "el4",
97                                      kmod => '1',
98                                      basearch => 'i386',
99                                      updaterepo => 'update',
100                                      results => 'rhel4/i386' },
101                  "epel-4-x86_64" => { osver => "el4",
102                                        kmod => '1',
103                                        basearch => 'x86_64',
104                                        updaterepo => 'update',
105                                        results => "rhel4/x86_64" },
106                  "epel-5-i386" => { osver => "el5", 
107                                       kmod => '1', 
108                                       basearch => 'i386',
109                                       updaterepo => 'update',
110                                       results => "rhel5/i386" },
111                  "epel-5-x86_64" => { osver => "el5",
112                                         kmod => '1',
113                                         basearch => 'x86_64',
114                                         updaterepo => 'update',
115                                         results => "rhel5/x86_64" },
116                  "epel-6-i386" => { osver => "el6", 
117                                       kmod => '1', 
118                                       basearch => 'i686',
119                                       updaterepo => 'update',
120                                       results => "rhel6/i686" },
121                  "epel-6-x86_64" => { osver => "el6",
122                                         kmod => '1',
123                                         basearch => 'x86_64',
124                                         updaterepo => 'update',
125                                         results => "rhel6/x86_64" },
126                  "fedora-14-i386" => { osver => "fc14",
127                                         kmod => "1",
128                                         basearch => "i686",
129                                         results => "fedora-14/i686" },
130                  "fedora-14-x86_64" => { osver => "fc14",
131                                         kmod => "1",
132                                         basearch => "x86_64",
133                                         results => "fedora-14/x86_64" },
134                  "fedora-15-i386" => { osver => "fc15",
135                                         kmod => "1",
136                                         basearch => "i686",
137                                         results => "fedora-15/i686" },
138                  "fedora-15-x86_64" => { osver => "fc15",
139                                         kmod => "1",
140                                         basearch => "x86_64",
141                                         results => "fedora-15/x86_64" },
142                  "fedora-development-i386" => { osver => "fcd",
143                                           kmod => '1',
144                                           basearch => 'i386',
145                                           results => 'fedora-devel/i386'},
146                  "fedora-development-x86_64" => { osver => "fcd",
147                                             kmod => '1',
148                                             basearch => 'x86_64',
149                                             results => 'fedora-devel/x86_64'} 
150 );
151
152 # The following are kernels that we can't successfully build modules against
153 # due to issues in the packaged kernel-devel RPM.
154
155 my %badkernels = (
156         "2.6.21-2950.fc8" => { "xen" => 1}, # Missing build ID
157 );
158
159 my $help;
160 my $ok = GetOptions("resultdir=s" => \$resultbase,
161                     "resultlist=s" => \$resultfile,
162                     "help" => \$help);
163
164 my @platforms = @ARGV;
165 my $srpm = pop @platforms;
166
167 if (!$ok || $help || !$srpm || $#platforms==-1) {
168   print "Usage: $0 [options] <platform> [<platform> [...]]  <srpm>\n";
169   print "    Options are : \n";
170   print "         --resultdir <dir>    Location to place output RPMS\n";
171   print "\n";
172   print "    Platform may be:\n";
173   foreach ("all", sort(keys(%platconf))) { print "        ".$_."\n"; };
174   exit(1);
175 }
176
177 my $oafsversion = `rpm -q --queryformat=%{VERSION} -p $srpm` or die $!;
178 chomp $oafsversion;
179 $oafsversion=~/([0-9]+)\.([0-9]+)\.([0-9]+)/;
180 my $major = $1;
181 my $minor = $2;
182 my $pathlevel = $3;
183
184 # OpenAFS SRPMs newer than 1.6.0 use the dist, rather than osvers variable
185
186 my $usedist = ($minor >= 6);
187
188 my $oafsrelease = `rpm -q --queryformat=%{RELEASE} -p $srpm` or die $!;
189 chomp $oafsrelease;
190
191 # Before we used the dist tag, the release variable of the srpm was 1.<release>
192 if (!$usedist) {
193         $oafsrelease=~s/^[^\.]*\.(.*)$/$1/;
194 }
195 print "Release is $oafsrelease\n";
196
197 if ($platforms[0] eq "all" and $#platforms == 0) {
198   @platforms = keys(%platconf);
199 }
200
201 foreach my $platform (@platforms) {
202   print "*******************************************************************\n";
203   print "Building for $platform\n";
204   die "Unknown platform $platform" if !$platconf{$platform};
205   my $osver = $platconf{$platform}{'osver'};
206   my $root = $rootbase.$platform."/root";
207   my $mockresults = $rootbase.$platform."/result";
208   my $resultdir = $resultbase."/".$platconf{$platform}{'results'};
209   my $basearch = $platconf{$platform}{'basearch'};
210   my $rpmstashdir = $stashbase.$platconf{$platform}{'results'}."/";
211
212   my $yumcachedir;
213   if (exists($platconf{$platform}{'updaterepo'})) {
214     $yumcachedir = $rootbase."cache/".$platform."/yum_cache/".
215                    $platconf{$platform}{'updaterepo'}."/packages/";
216   }
217
218   File::Path::mkpath($resultdir, 0, 0755);
219
220   if (system($mockcommand, "-r", $platform, "init") != 0) {
221     die "Initialising the root failed: $?\n";
222   }
223
224   my %modulelist;
225
226   print "-------------------------------------------------------------------\n";
227   print "Finding available kernel modules\n";
228
229   my $arbitraryversion = "";
230
231   my @kernels;
232   if ($platform=~/fedora-development/) {
233     @kernels = findKernels($root, $platform, 0, "kernel-devel");
234   } elsif ($platform=~/centos-4/) {
235     @kernels = findKernels($root, $platform, 0, "kernel-devel", "kernel-smp-devel", 
236                                  "kernel-hugemem-devel", "kernel-xenU-devel");
237   } else {
238     @kernels = findKernels($root, $platform, 0, 'kernel-devel');
239   }
240
241   foreach my $kernel (@kernels) {
242       chomp $kernel;
243       my ($package, $version)=split(/\s+/, $kernel);
244       my ($arch) = ($package=~/\.(.*)$/);
245       my ($variant) = ($package=~/kernel-(.*)-devel/);
246       $variant = "" if !defined($variant);
247       next if ($package !~ /^kernel/);
248       next if ($arch eq "noarch");
249       next 
250           if (exists($badkernels{$version}) && ($badkernels{$version}{$variant}));
251       next if ($variant =~/debug$/); # Fedora debug kernels are bad
252       next if ($kernel !~ /$osver/ ); # fc15 kernel in fc14 repo?
253
254       print "$arch : $variant : $version\n";
255       $modulelist{$arch} ={} if !$modulelist{$arch};
256       $modulelist{$arch}{$version} = {} if !$modulelist{$arch}{$version};
257       $modulelist{$arch}{$version}{$variant} = 1;
258       $arbitraryversion = $version;
259   }
260
261   if (!$arbitraryversion) {
262     die "Unable to find a valid kernel-devel package for $platform\n";
263   }
264
265   print "-------------------------------------------------------------------\n";
266   print "Building the userland RPMs\n";
267   my @rpms = ('openafs', 'openafs-authlibs', 'openafs-authlibs-devel', 
268               'openafs-client', 'openafs-compat', 'openafs-debuginfo', 
269               'openafs-devel', 'openafs-docs', 'openafs-kernel-source', 
270               'openafs-kpasswd', 'openafs-krb5', 'openafs-server',
271               'dkms-openafs');
272   my @missingrpms=();
273
274   my $missing = 0;
275   foreach my $rpm (@rpms) {
276     my $rpmname;
277     if ($usedist) {
278         $rpmname = $rpm."-".$oafsversion."-".$oafsrelease.".".$osver.".".
279                    $basearch.".rpm";
280     } else {
281         $rpmname = $rpm."-".$oafsversion."-".$osver.".".$oafsrelease.".".
282                    $basearch.".rpm";
283     }
284     if (! -f $resultdir."/".$rpmname) {
285       $missing++;
286       print "$resultdir/$rpmname is missing!\n";
287       push @missingrpms, $rpmname;
288     }
289   }
290   if ($missing) {
291     system($mockcommand." -r ".$platform." rebuild ".
292                         ' --define "fedorakmod 1" '.
293                         ' --define "kernvers '.$arbitraryversion.'" '.
294                         ' --define "osvers '.$osver.'" '.
295                         ' --define "dist .'.$osver.'" '.
296                         ' --define "build_modules 0" '.
297                         ' --define "build_userspace 1" '.
298                         ' --define "build_authlibs 1" '.
299                         $srpm) == 0
300       or die "build failed with : $!\n";
301     foreach my $rpmname (@missingrpms) {
302       system("cp ".$mockresults."/".$rpmname." ".$resultdir) == 0
303           or die "Copy failed with : $!\n";
304       push @newrpms, $resultdir."/".$rpmname;
305     }
306   } else {
307     print "All userland RPMs present for $platform. Skipping build\n";
308   }
309
310   print "-------------------------------------------------------------------\n";
311   print "Building kernel modules\n";
312
313   foreach my $arch (keys(%modulelist)) {
314     foreach my $version (keys(%{$modulelist{$arch}})) {
315       my $kversion = $version;
316       $kversion=~s/-/_/g;
317       my @tobuild;
318
319       if ($buildall) {
320         @tobuild = keys(%{$modulelist{$arch}{$version}});
321       } else {
322         foreach my $variant (keys(%{$modulelist{$arch}{$version}})) {
323           my $dvariant=$variant;
324           $dvariant.="-" if ($dvariant);
325           if (!-f $resultdir."/kmod-openafs-".$dvariant.
326                   $oafsversion."-".$oafsrelease.".".$kversion.".".
327                   $arch.".rpm") {
328             my @done = glob ($resultdir."/kmod-openafs-".$dvariant.
329                              $oafsversion."-*.".$kversion.".".$arch.".rpm");
330
331             if ($ignorerelease && $#done>=0) {
332               print "Kernel module for $kversion already exists for an".
333                     "older release. Skipping building it this time.\n";
334             } else {
335               push @tobuild, $variant;
336               print $resultdir."/kmod-openafs-".$dvariant.
337                     $oafsversion."-".$oafsrelease.".".$kversion.".".
338                     $arch.".rpm is missing\n";
339             }
340           }
341         }
342       }
343
344       if ($#tobuild>=0) {
345         my $variants = join(" ", map {$_ or '\\\\\"\\\\\"'} @tobuild);
346         print "Building $arch module for kernel $version with variants $variants\n";
347         system ("setarch $arch $mockcommand -r $platform rebuild ".
348                              " --arch ".$arch.
349                              ' --define "fedorakmod 1" '.
350                              ' --define "osvers '.$osver.'" '.
351                              ' --define "dist .'.$osver.'" '.
352                              ' --define "kernvers '.$version.'" '.
353                              ' --define "kvariants '.$variants.'" '.
354                              ' --define "build_modules 1" '.
355                              ' --define "build_userspace 0" '.
356                              $srpm) == 0
357           or die "Build failed with : $!\n";
358         foreach my $variant (@tobuild) {
359           if ($variant) {
360             $variant.="-";
361           }
362           system("cp ".$mockresults."/kmod-openafs-".$variant.$oafsversion."-".$oafsrelease.".".$kversion.".".$arch.".rpm $resultdir") == 0
363             or die "Copy failed with : $!\n";
364           push @newrpms, $resultdir."/kmod-openafs-".$variant.$oafsversion."-".$oafsrelease.".".$kversion.".".$arch.".rpm";
365         }
366       } else {
367          print "All kernel modules already built for $version on $arch\n";
368       }
369     }
370   }
371   print "-------------------------------------------------------------------\n";
372   print "Creating repository data\n";
373   system ("cd $resultdir; createrepo .") == 0
374     or die "Unable to build repository data\n";
375
376   if ($yumcachedir) {
377     print "-------------------------------------------------------------------\n";
378     print "Stashing kernel-devel RPMs\n";
379   
380     my $changed;
381     my $dirh = IO::Dir->new($yumcachedir);
382     if (defined($dirh)) {
383       my $file;
384       while (defined($file = $dirh->read)) {
385         if ( $file=~/^kernel.*devel/ &&
386               -f $yumcachedir.$file && ! -f $rpmstashdir.$file) {
387           print "Stashing $file for later use\n";
388           system("cp ".$yumcachedir.$file." ".$rpmstashdir.$file) == 0
389             or die "Copy failed with : $!\n";
390           $changed++;
391         }
392       }
393     }
394  
395     if ($changed) {
396       print "Updating stash repodata\n";
397       system ("cd $rpmstashdir; createrepo .") == 0
398         or die "Unable to update RPM stash repository data\n";
399     }
400   }
401 }
402
403 print "=====================================================================\n";
404 print "All builds complete\nBuilt:\n";
405 print join("\n",@newrpms);
406 if (defined($resultfile)) {
407   my $resultfh=new IO::File $resultfile, 'w';
408   print $resultfh join("\n",@newrpms);
409 }
410