source: ProjectBuilder/devel/pb/lib/ProjectBuilder/Distribution.pm@ 391

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