source: ProjectBuilder/devel/pb-modules/lib/ProjectBuilder/Distribution.pm@ 423

Last change on this file since 423 was 423, checked in by Bruno Cornec, 16 years ago
  • Improved pbdistrocheck to support -v flags
  • Fix Ubuntu issue on distribution detection
  • some more pb_log added
File size: 9.9 KB
Line 
1#!/usr/bin/perl -w
2#
3# Creates common environment for distributions
4#
5# $Id$
6#
7
8package ProjectBuilder::Distribution;
9
10use strict;
11use Data::Dumper;
12use ProjectBuilder::Base;
13
14# Inherit from the "Exporter" module which handles exporting functions.
15
16use Exporter;
17
18# Export, by default, all the functions into the namespace of
19# any code which uses this module.
20
21our @ISA = qw(Exporter);
22our @EXPORT = qw(pb_distro_init pb_get_distro);
23
24=pod
25
26=head1 NAME
27
28ProjectBuilder::Distribution, part of the project-builder.org - module dealing with distribution detection
29
30=head1 DESCRIPTION
31
32This modules provides functions to allow detection of Linux distributions, and giving back some attributes concerning them.
33
34=head1 SYNOPSIS
35
36 use ProjectBuilder::Distribution;
37
38 #
39 # Return information on the running distro
40 #
41 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init();
42 print "distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n";
43 #
44 # Return information on the requested distro
45 #
46 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init("ubuntu","7.10");
47 print "distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n";
48 #
49 # Return information on the running distro
50 #
51 my ($ddir,$dver) = pb_get_distro();
52 my ($ddir, $dver, $dfam, $dtype, $pbsuf) = pb_distro_init($ddir,$dver);
53 print "distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $pbsuf)."\n";
54
55=head1 USAGE
56
57=over 4
58
59
60=item B<pb_get_distro>
61
62This function returns a list of 2 parameters indicating the distribution name and version of the underlying Linux distribution. The value of those 2 fields may be "unknown" in case the function was unable to recognize on which distribution it is running.
63
64On my home machine it would currently report ("mandriva","2008.0").
65
66=cut
67
68sub pb_distro_init {
69
70my $ddir = shift || undef;
71my $dver = shift || undef;
72my $dfam = "unknown";
73my $dtype = "unknown";
74my $dsuf = "unknown";
75
76# If we don't know which distribution we're on, then guess it
77($ddir,$dver) = pb_get_distro() if ((not defined $ddir) || (not defined $dver));
78
79# There should be unicity of names between ddir dfam and dtype
80# In case of duplicate, bad things can happen
81if (($ddir =~ /debian/) ||
82 ($ddir =~ /ubuntu/)) {
83 $dfam="du";
84 $dtype="deb";
85 $dsuf=".$ddir$dver";
86} elsif ($ddir =~ /gentoo/) {
87 $dfam="gen";
88 $dtype="ebuild";
89 $dver="nover";
90 $dsuf=".$ddir";
91} elsif ($ddir =~ /slackware/) {
92 $dfam="slack";
93 $dtype="tgz";
94 $dsuf=".$dfam$dver";
95} elsif (($ddir =~ /suse/) ||
96 ($ddir =~ /sles/)) {
97 if ($ddir =~ /opensuse/) {
98 $ddir = "suse";
99 }
100 $dfam="novell";
101 $dtype="rpm";
102 $dsuf=".$ddir$dver";
103} elsif (($ddir =~ /redhat/) ||
104 ($ddir =~ /rhel/) ||
105 ($ddir =~ /fedora/) ||
106 ($ddir =~ /vmware/) ||
107 ($ddir =~ /centos/)) {
108 $dfam="rh";
109 $dtype="rpm";
110 my $dver1 = $dver;
111 $dver1 =~ s/\.//;
112 if ($ddir =~ /fedora/) {
113 $dsuf=".fc$dver1";
114 } elsif ($ddir =~ /redhat/) {
115 $dsuf=".rh$dver1";
116 } elsif ($ddir =~ /vmware/) {
117 $dsuf=".vwm$dver1";
118 } else {
119 $dsuf=".$ddir$dver1";
120 }
121} elsif (($ddir =~ /mandrake/) ||
122 ($ddir =~ /mandrakelinux/) ||
123 ($ddir =~ /mandriva/)) {
124 $dfam="md";
125 $dtype="rpm";
126 if ($ddir =~ /mandrakelinux/) {
127 $ddir = "mandrake";
128 }
129 if ($ddir =~ /mandrake/) {
130 my $dver1 = $dver;
131 $dver1 =~ s/\.//;
132 $dsuf=".mdk$dver1";
133 } else {
134 $dsuf=".mdv$dver";
135 }
136} elsif ($ddir =~ /freebsd/) {
137 $dfam="bsd";
138 $dtype="port";
139 my $dver1 = $dver;
140 $dver1 =~ s/\.//;
141 $dsuf=".$dfam$dver1";
142} else {
143 $dfam="unknown";
144 $dtype="unknown";
145 $dsuf="unknown";
146}
147
148return($ddir, $dver, $dfam, $dtype, $dsuf);
149}
150
151=item B<pb_distro_init>
152
153This function returns a list of 5 parameters indicating the distribution name, version, family, type of build system and suffix of packages of the underlying Linux distribution. The value of the 5 fields may be "unknown" in case the function was unable to recognize on which distribution it is running.
154
155As an example, Ubuntu and Debian are in the same "du" family. As well as RedHat, RHEL, CentOS, fedora are on the same "rh" family.
156Mandriva, Open SuSE and Fedora have all the same "rpm" type of build system. Ubuntu ad Debian have the same "deb" type of build system.
157And "fc" is the extension generated for all Fedora packages (Version will be added by pb).
158
159When passing the distribution name and version as parameters, the B<pb_distro_init> function returns the parameter of that distribution instead of the underlying one.
160
161Cf: http://linuxmafia.com/faq/Admin/release-files.html
162Ideas taken from http://search.cpan.org/~kerberus/Linux-Distribution-0.14/lib/Linux/Distribution.pm
163
164=cut
165
166sub pb_get_distro {
167
168my $base="/etc";
169
170# List of files that unambiguously indicates what distro we have
171my %single_rel_files = (
172# Tested
173 'gentoo' => 'gentoo-release', # >= 1.6
174 'slackware' => 'slackware-version', # >= 10.2
175 'mandriva' => 'mandriva-release', # >=2006.0
176 'mandrakelinux' => 'mandrakelinux-release',# = 10.2
177 'fedora' => 'fedora-release', # >= 4
178 'vmware' => 'vmware-release', # >= 3
179 'sles' => 'sles-release', # Doesn't exist as of 10
180# Untested
181 'knoppix' => 'knoppix_version', #
182 'yellowdog' => 'yellowdog-release', #
183 'esmith' => 'e-smith-release', #
184 'turbolinux' => 'turbolinux-release', #
185 'blackcat' => 'blackcat-release', #
186 'aurox' => 'aurox-release', #
187 'annvix' => 'annvix-release', #
188 'cobalt' => 'cobalt-release', #
189 'redflag' => 'redflag-release', #
190 'ark' => 'ark-release', #
191 'pld' => 'pld-release', #
192 'nld' => 'nld-release', #
193 'lfs' => 'lfs-release', #
194 'mk' => 'mk-release', #
195 'conectiva' => 'conectiva-release', #
196 'immunix' => 'immunix-release', #
197 'tinysofa' => 'tinysofa-release', #
198 'trustix' => 'trustix-release', #
199 'adamantix' => 'adamantix_version', #
200 'yoper' => 'yoper-release', #
201 'arch' => 'arch-release', #
202 'libranet' => 'libranet_version', #
203 'valinux' => 'va-release', #
204 'yellowdog' => 'yellowdog-release', #
205 'ultrapenguin' => 'ultrapenguin-release', #
206 );
207
208# List of files that ambiguously indicates what distro we have
209my %ambiguous_rel_files = (
210 'mandrake' => 'mandrake-release', # <= 10.1
211 'debian' => 'debian_version', # >= 3.1
212 'suse' => 'SuSE-release', # >= 10.0
213 'redhat' => 'redhat-release', # >= 7.3
214 'lsb' => 'lsb-release', # ???
215 );
216
217# Should have the same keys as the previous one.
218# If ambiguity, which other distributions should be checked
219my %distro_similar = (
220 'mandrake' => ['mandrake', 'mandrakelinux'],
221 'debian' => ['debian', 'ubuntu'],
222 'suse' => ['suse', 'sles', 'opensuse'],
223 'redhat' => ['redhat', 'rhel', 'centos', 'mandrake', 'vmware'],
224 'lsb' => ['ubuntu', 'lsb'],
225 );
226
227my %distro_match = (
228# Tested
229 'gentoo' => '.* version (.+)',
230 'slackware' => 'S[^ ]* (.+)$',
231# There should be no ambiguity between potential ambiguous distro
232 'mandrakelinux' => 'Mandrakelinux release (.+) \(',
233 'mandrake' => 'Mandr[^ ]* release (.+) \(',
234 'mandriva' => 'Mandr[^ ]* [^ ]* release (.+) \(',
235 'fedora' => 'Fedora .*release (\d+) \(',
236 'vmware' => 'VMware ESX Server (\d+) \(',
237 'rhel' => 'Red Hat Enterprise Linux .*release (.+) \(',
238 'centos' => '.*CentOS .*release (.+) ',
239 'redhat' => 'Red Hat Linux release (.+) \(',
240 'sles' => 'SUSE .* Enterprise Server (\d+) \(',
241 'suse' => 'SUSE LINUX (\d.+) \(',
242 'opensuse' => 'openSUSE (\d.+) \(',
243 'lsb' => '.*[^Ubunt].*\nDISTRIB_RELEASE=(.+)',
244# Ubuntu includes a /etc/debian_version file that cretaes an ambiguity with debian
245# So we need to look at distros in reverse alphabetic order to treat ubuntu always first
246 'ubuntu' => '.*Ubuntu.*\nDISTRIB_RELEASE=(.+)',
247 'debian' => '(.+)',
248# Not tested
249 'arch' => '.* ([0-9.]+) .*',
250 'redflag' => 'Red Flag (?:Desktop|Linux) (?:release |\()(.*?)(?: \(.+)?\)',
251);
252
253my $release;
254my $distro;
255
256# Begin to test presence of non-ambiguous files
257# that way we reduce the choice
258my ($d,$r);
259while (($d,$r) = each %single_rel_files) {
260 if (-f "$base/$r" && ! -l "$base/$r") {
261 my $tmp=pb_get_content("$base/$r");
262 # Found the only possibility.
263 # Try to get version and return
264 if (defined ($distro_match{$d})) {
265 ($release) = $tmp =~ m/$distro_match{$d}/m;
266 } else {
267 print STDERR "Unable to find $d version in $r\n";
268 print STDERR "Please report to the maintainer bruno_at_project-builder.org\n";
269 $release = "unknown";
270 }
271 return($d,$release);
272 }
273}
274
275# Now look at ambiguous files
276# Ubuntu includes a /etc/debian_version file that creates an ambiguity with debian
277# So we need to look at distros in reverse alphabetic order to treat ubuntu always first via lsb
278foreach $d (reverse keys %ambiguous_rel_files) {
279 $r = $ambiguous_rel_files{$d};
280 if (-f "$base/$r" && !-l "$base/$r") {
281 # Found one possibility.
282 # Get all distros concerned by that file
283 my $tmp=pb_get_content("$base/$r");
284 my $found = 0;
285 my $ptr = $distro_similar{$d};
286 pb_log(2,"amb: ".Dumper($ptr)."\n");
287 $release = "unknown";
288 foreach my $dd (@$ptr) {
289 pb_log(2,"check $dd\n");
290 # Try to check pattern
291 if (defined $distro_match{$dd}) {
292 pb_log(2,"cmp: $distro_match{$dd} - vs - $tmp\n");
293 ($release) = $tmp =~ m/$distro_match{$dd}/m;
294 if ((defined $release) && ($release ne "unknown")) {
295 $distro = $dd;
296 $found = 1;
297 last;
298 }
299 }
300 }
301 if ($found == 0) {
302 print STDERR "Unable to find $d version in $r\n";
303 print STDERR "Please report to the maintainer bruno_at_project-builder.org\n";
304 $release = "unknown";
305 } else {
306 return($distro,$release);
307 }
308 }
309}
310return("unknown","unknown");
311}
312
313=back
314
315=head1 WEB SITES
316
317The main Web site of the project is available at L<http://www.project-builder.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
318
319=head1 USER MAILING LIST
320
321None exists for the moment.
322
323=head1 AUTHORS
324
325The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
326
327=head1 COPYRIGHT
328
329Project-Builder.org is distributed under the GPL v2.0 license
330described in the file C<COPYING> included with the distribution.
331
332=cut
333
334
3351;
Note: See TracBrowser for help on using the repository browser.