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