ace74ca6b9222ca8e76b6d720cdab8e3108f349c
[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
14 my $suser="nsu";
15 my $rootbase="/var/lib/mock/";
16 my $resultbase="/tmp/result/";
17 my $stashbase="/disk/scratch/repository/";
18 my $mockcommand = "/usr/bin/mock";
19 my $buildall = 0;
20 my $ignorerelease = 1;
21 my @newrpms;
22
23 my %platconf = ( "fedora-5-i386" => { osver => "fc5",
24                                       kmod => '1',
25                                       basearch => 'i386',
26                                       updaterepo => 'updates-released',
27                                       results => 'fc5/i386' },
28                  "fedora-5-x86_64" => { osver => "fc5",
29                                        kmod => '1',
30                                        basearch => 'x86_64',
31                                        updaterepo => 'updates-released',
32                                        results => 'fc5/x86_64' },
33                  "fedora-6-i386" => { osver => "fc6", 
34                                       kmod => '1', 
35                                       basearch => 'i386',
36                                       updaterepo => 'updates-released',
37                                       results => "fc6/i386" },
38                  "fedora-6-x86_64" => { osver => "fc6",
39                                         kmod => '1',
40                                         basearch => 'x86_64',
41                                         updaterepo => 'updates-released',
42                                         results => "fc6/x86_64" },
43                  "fedora-7-i386" => { osver => "fc7", 
44                                       kmod => '1', 
45                                       basearch => 'i386',
46                                       updaterepo => 'updates-released',
47                                       results => "fc7/i386" },
48                  "fedora-7-x86_64" => { osver => "fc7",
49                                         kmod => '1',
50                                         basearch => 'x86_64',
51                                         updaterepo => 'updates-released',
52                                         results => "fc7/x86_64" },
53                  "fedora-8-i386" => { osver => "fc8", 
54                                       kmod => '1', 
55                                       basearch => 'i386',
56                                       updaterepo => 'updates-released',
57                                       results => "fc8/i386" },
58                  "fedora-8-x86_64" => { osver => "fc8",
59                                         kmod => '1',
60                                         basearch => 'x86_64',
61                                         updaterepo => 'updates-released',
62                                         results => "fc8/x86_64" },
63                  "centos-4-i386" => { osver => "el4",
64                                      kmod => '1',
65                                      basearch => 'i386',
66                                      updaterepo => 'update',
67                                      results => 'el4/i386' },
68                  "centos-4-x86_64" => { osver => "el4",
69                                        kmod => '1',
70                                        basearch => 'x86_64',
71                                        updaterepo => 'update',
72                                        results => "el4/x86_64" },
73                  "centos-5-i386" => { osver => "el5", 
74                                       kmod => '1', 
75                                       basearch => 'i386',
76                                       updaterepo => 'update',
77                                       results => "el5/i386" },
78                  "centos-5-x86_64" => { osver => "el5",
79                                         kmod => '1',
80                                         basearch => 'x86_64',
81                                         updaterepo => 'update',
82                                         results => "el5/x86_64" },
83 #                "fedora-development-i386" => { osver => "fcd",
84 #                                         kmod => '1',
85 #                                         basearch => 'i386',
86 #                                         results => 'fedora-devel/i386'},
87 #                "fedora-development-x86_64" => { osver => "fcd",
88 #                                           kmod => '1',
89 #                                           basearch => 'x86_64',
90 #                                           results => 'fedora-devel/x86_64'} 
91 );
92
93 # The following are kernels that we can't successfully build modules against
94 # due to issues in the packaged kernel-devel RPM.
95
96 my %badkernels = (
97         "2.6.21-2950.fc8" => { "xen" => 1} # Missing build ID
98 );
99
100 my $help;
101 my $ok = GetOptions("resultdir=s" => \$resultbase,
102                     "help" => \$help);
103
104 my @platforms = @ARGV;
105 my $srpm = pop @platforms;
106
107 if (!$ok || $help || !$srpm || $#platforms==-1) {
108   print "Usage: $0 [options] <platform> [<platform> [...]]  <srpm>\n";
109   print "    Options are : \n";
110   print "         --resultdir <dir>    Location to place output RPMS\n";
111   print "\n";
112   print "    Platform may be:\n";
113   foreach ("all", sort(keys(%platconf))) { print "        ".$_."\n"; };
114   exit(1);
115 }
116
117 my $oafsversion = `rpm -q --queryformat=%{VERSION} -p $srpm` or die $!;
118 chomp $oafsversion;
119 my $oafsrelease = `rpm -q --queryformat=%{RELEASE} -p $srpm` or die $!;
120 chomp $oafsrelease;
121 $oafsrelease=~s/^[^\.]*\.(.*)$/$1/;
122
123 print "Release is $oafsrelease\n";
124
125 if ($platforms[0] eq "all" and $#platforms == 0) {
126   @platforms = keys(%platconf);
127 }
128
129 foreach my $platform (@platforms) {
130   print "*******************************************************************\n";
131   print "Building for $platform\n";
132   die "Unknown platform $platform" if !$platconf{$platform};
133   my $osver = $platconf{$platform}{'osver'};
134   my $root = $rootbase.$platform."/root";
135   my $mockresults = $rootbase.$platform."/result";
136   my $resultdir = $resultbase.$platconf{$platform}{'results'};
137   my $basearch = $platconf{$platform}{'basearch'};
138   my $rpmstashdir = $stashbase.$platconf{$platform}{'results'}."/";
139
140   my $yumcachedir;
141   if (exists($platconf{$platform}{'updaterepo'})) {
142     $yumcachedir = $rootbase."cache/".$platform."/yum_cache/".
143                    $platconf{$platform}{'updaterepo'}."/packages/";
144   }
145
146   File::Path::mkpath($resultdir, 0, 0755);
147
148   if (system($mockcommand, "-r", $platform, "init") != 0) {
149     die "Initialising the root failed: $?\n";
150   }
151
152   my %modulelist;
153
154   print "-------------------------------------------------------------------\n";
155   print "Finding available kernel modules\n";
156
157   my $arbitraryversion = "";
158   my $modules=`$suser -c 'yum --installroot $root provides kernel-devel'`;
159   if ($modules eq "") {
160       $modules=`$suser -c 'yum -d 2 --installroot $root provides kernel-devel'`;
161       my $modulen;
162       my %modulel;
163       foreach $modulen (split(/\n/, $modules)) {
164           my ($pk, $colon, $comment)=split(/\s+/, $modulen);
165           if ($pk =~ /^kernel/) {
166               $modulel{$pk} = "$pk";
167           } 
168       }
169       $modulen=join(" ", keys(%modulel));
170       $modules=`$suser -c 'yum --installroot $root list $modulen'`;
171   }
172   foreach my $module (split(/\n/, $modules)) {
173       my ($package, $version, $repo)=split(/\s+/, $module);
174       my ($arch) = ($package=~/\.(.*)$/);
175       my ($variant) = ($package=~/kernel-(.*)-devel/);
176       $variant = "" if !defined($variant);
177       next if ($package !~ /^kernel/);
178       next if ($arch eq "noarch");
179       next 
180           if (exists($badkernels{$version}) && ($badkernels{$version}{$variant}));
181       if ($platform=~/fedora-5/) {
182           next if ($variant eq "xen0"); # Fedora 5 has some bad xen0 kernel-devels
183           next if ($variant eq "smp");
184       }
185       if ($platform=~/fedora-8/) {
186           next if ($variant =~/debug$/); # Fedora 8 debug kernels are bad
187       }
188       print "$arch : $variant : $version\n";
189       $modulelist{$arch} ={} if !$modulelist{$arch};
190       $modulelist{$arch}{$version} = {} if !$modulelist{$arch}{$version};
191       $modulelist{$arch}{$version}{$variant} = 1;
192       $arbitraryversion = $version;
193   }
194
195   if (!$arbitraryversion) {
196     die "Unable to find a valid kernel-devel package for $platform\n";
197   }
198
199   print "-------------------------------------------------------------------\n";
200   print "Building the userland RPMs\n";
201   my @rpms = ('', '-authlibs', '-authlibs-devel', '-client', '-compat',
202               '-debuginfo', '-devel', '-docs', '-kernel-source', '-kpasswd',
203               '-krb5', '-server');
204
205   my $missing = 0;
206   foreach my $rpm (@rpms) {
207     if (! -f $resultdir."/openafs".$rpm."-".$oafsversion."-".$osver.".".
208              $oafsrelease.".".$basearch.".rpm") {
209       $missing++;
210       print $resultdir."/openafs".$rpm."-".$oafsversion."-".$osver.".".
211             $oafsrelease.".".$basearch.".rpm is missing!\n"
212     }
213   }
214   if ($missing) {
215     system($mockcommand." -r ".$platform." rebuild ".
216                         ' --define "fedorakmod 1" '.
217                         ' --define "kernvers '.$arbitraryversion.'" '.
218                         ' --define "osvers '.$osver.'" '.
219                         ' --define "build_modules 0" '.
220                         ' --define "build_userspace 1" '.
221                         ' --define "build_authlibs 1" '.
222                         $srpm) == 0
223       or die "build failed with : $!\n";
224     foreach my $rpm (@rpms) {
225       system("cp ".$mockresults."/openafs".$rpm."-".$oafsversion."-".
226                    $osver.".".$oafsrelease.".".$basearch.".rpm ".
227                    $resultdir) == 0
228           or die "Copy failed with : $!\n";
229       push @newrpms, $mockresults."/openafs".$rpm."-".$oafsversion."-".
230                      $osver.".".$oafsrelease.".".$basearch.".rpm";
231     }
232   } else {
233     print "All userland RPMs present for $platform. Skipping build\n";
234   }
235
236    print "-------------------------------------------------------------------\n";
237   print "Building kernel modules\n";
238
239  foreach my $arch (keys(%modulelist)) {
240     foreach my $version (keys(%{$modulelist{$arch}})) {
241       my $kversion = $version;
242       $kversion=~s/-/_/g;
243       my @tobuild;
244
245       if ($buildall) {
246         @tobuild = keys(%{$modulelist{$arch}{$version}});
247       } else {
248         foreach my $variant (keys(%{$modulelist{$arch}{$version}})) {
249           my $dvariant=$variant;
250           $dvariant.="-" if ($dvariant);
251           if (!-f $resultdir."/kmod-openafs-".$dvariant.
252                   $oafsversion."-".$oafsrelease.".".$kversion.".".
253                   $arch.".rpm") {
254             my @done = glob ($resultdir."/kmod-openafs-".$dvariant.
255                              $oafsversion."-*.".$kversion.".".$arch.".rpm");
256
257             if ($ignorerelease && $#done>=0) {
258               print "Kernel module for $kversion already exists for an".
259                     "older release. Skipping building it this time.\n";
260             } else {
261               push @tobuild, $variant;
262               print $resultdir."/kmod-openafs-".$dvariant.
263                     $oafsversion."-".$oafsrelease.".".$kversion.".".
264                     $arch.".rpm is missing\n";
265             }
266           }
267         }
268       }
269
270       if ($#tobuild>=0) {
271         my $variants = join(" ", map {$_ or '\\\\\"\\\\\"'} @tobuild);
272         print "Building $arch module for kernel $version with variants $variants\n";
273         system ("setarch $arch $mockcommand -r $platform rebuild ".
274                              " --arch ".$arch.
275                              ' --define "fedorakmod 1" '.
276                              ' --define "osvers '.$osver.'" '.
277                              ' --define "kernvers '.$version.'" '.
278                              ' --define "kvariants '.$variants.'" '.
279                              ' --define "build_modules 1" '.
280                              ' --define "build_userspace 0" '.
281                              $srpm) == 0
282           or die "Build failed with : $!\n";
283         foreach my $variant (@tobuild) {
284           if ($variant) {
285             $variant.="-";
286           }
287           system("cp ".$mockresults."/kmod-openafs-".$variant.$oafsversion."-".$oafsrelease.".".$kversion.".".$arch.".rpm $resultdir") == 0
288             or die "Copy failed with : $!\n";
289           push @newrpms, $mockresults."/kmod-openafs-".$variant.$oafsversion."-".$oafsrelease.".".$kversion.".".$arch.".rpm";
290         }
291       } else {
292          print "All kernel modules already built for $version on $arch\n";
293       }
294     }
295   }
296   print "-------------------------------------------------------------------\n";
297   print "Creating repository data\n";
298   system ("cd $resultdir; createrepo .") == 0
299     or die "Unable to build repository data\n";
300
301   if ($yumcachedir) {
302     print "-------------------------------------------------------------------\n";
303     print "Stashing kernel-devel RPMs\n";
304   
305     my $changed;
306     my $dirh = IO::Dir->new($yumcachedir);
307     if (defined($dirh)) {
308       my $file;
309       while (defined($file = $dirh->read)) {
310         if ( $file=~/^kernel.*devel/ &&
311               -f $yumcachedir.$file && ! -f $rpmstashdir.$file) {
312           print "Stashing $file for later use\n";
313           system("cp ".$yumcachedir.$file." ".$rpmstashdir.$file) == 0
314             or die "Copy failed with : $!\n";
315           $changed++;
316         }
317       }
318     }
319  
320     if ($changed) {
321       print "Updating stash repodata\n";
322       system ("cd $rpmstashdir; createrepo .") == 0
323         or die "Unable to update RPM stash repository data\n";
324     }
325   }
326 }
327
328 print "=====================================================================\n";
329 print "All builds complete\nBuilt:\n";
330 print join("\n",@newrpms);
331