#!/usr/bin/perl use strict; use warnings; use MDV::Distribconf::Build; use Getopt::Long; use Pod::Usage; my $VERSION = '0.02'; my %urpmfiles; =head1 NAME gendistrib - generates a mirror tree for a distribution =head1 SYNOPSIS gendistrib [options] directory =head1 OPTIONS =over 4 =item --blind Always rebuild indexes, without checking whether it's needed. =item --compss file Path of F file (defaults to F). =item --depslist file Path of F file (defaults to F). =item --destdir dir Create all new files in the specified directory. All subdirectories should exist. This option is mostly useful for testing, or while using a read-only repository. =item --hdlists file Path of the F file (defaults to F) =item --headersdir dir Put temporary files in this directory (defaults to TMPDIR). =item --mediacfg file Use the specified F file (defaults to F). =item --nobadrpm Don't abort when encountering bad rpms. =item --chkdep Search for missing dependencies. =item --noclean Keep cache files. =item --noemptymedia Stop and abort if an empty media is found. =item --nomd5sum Don't generate MD5SUM files. =item --nomediainfo Don't create per-media F subdirectories. =item --provides file Path of F file (defaults to F) =item --skipmissingdir If a media dir is missing, ignore it instead of aborting. =item -s Silent mode. =back =cut GetOptions( 'blind' => \my $blind, 'compss=s' => \$urpmfiles{compss}, 'depslist=s' => \$urpmfiles{depslist}, 'destdir=s' => \my $destdir, 'hdlists=s' => \$urpmfiles{hdlists}, 'headersdir=s' => \my $headers_dir, 'help|h' => \&usage, 'mediacfg=s' => \$urpmfiles{mediacfg}, 'nobadrpm' => \my $dontdie, 'nochkdep' => \my $nochkdep, # compatibility, default now 'chkdep' => \my $chkdep, 'noclean' => \my $noclean, 'noemptymedia' => \my $noemptymedia, 'nomd5sum' => \my $nomd5sum, 'nomediainfo' => \my $nomediainfo, 'provides=s' => \$urpmfiles{provides}, 'skipmissingdir' => \my $skipmissingdir, 's' => \my $nooutput, 'v|version' => sub { warn "$0 version $VERSION\n"; exit 0 }, 'h|help' => sub { pod2usage(0) }, 'fork' => \my $fork, ) or pod2usage(); my @distrib; foreach (@ARGV) { my $mdg = MDV::Distribconf::Build->new($_); if ( !$mdg->loadtree() ) { printf STDERR "%s seems to no contains any distrib... skipping\n", $mdg->getfullpath( undef, 'root' ); next; } else { if ( defined( $urpmfiles{mediacfg} ) ) { $mdg->parse_mediacfg( $urpmfiles{mediacfg} ) or do { print STDERR "Can't read $urpmfiles{mediacfg}\n"; next; }; } elsif ( defined( $urpmfiles{hdlists} ) ) { $mdg->parse_hdlists( $urpmfiles{hdlists} ) or do { print STDERR "Can't read $urpmfiles{hdlists}\n"; next; }; } else { $mdg->parse_mediacfg || $mdg->parse_hdlists or do { print STDERR "Can't read the distrib config\n"; next; }; } # Error which are fatale my @fatal = qw(SAME_INDEX); push( @fatal, 'MISSING_MEDIADIR' ) unless ($skipmissingdir); my @IGNORE = qw(MISSING_INDEX); my ( @fatalerrors, @errors, $have_misssing_dir ) ; # fatales error show at the end $mdg->check( sub { my %info = @_; grep { $_ eq $info{errcode} } @IGNORE and return; $have_misssing_dir = 1 if ( $info{errcode} eq 'MISSING_MEDIADIR' ); if ( grep { $_ eq $info{errcode} } @fatal ) { push( @fatalerrors, "$info{level}: $info{message}" ); } else { push( @errors, "$info{level}: $info{message}" ) unless ($nooutput); } } ); if ( @errors || @fatalerrors ) { printf STDERR "Errors found while checking %s:\n", $mdg->{root}; print "$_\n" foreach (@errors); } if (@fatalerrors) { printf STDERR <getpath( undef, 'root' ), $mdg->getvalue( undef, 'version' ), $mdg->getvalue( undef, 'arch' ), ) unless ($nooutput); $mdg->load_all_medias(); my $mustdie = 0; if ($fork) { $mdg->push_temp_files(); $mdg->link_index_to_distrib(); my $pid = fork(); if ( defined($pid) ) { if ($pid) { $mdg->{noclean} = 1; next; } else { $mustdie = 1; } } } if ( $mdg->list_unsynch_medias() ) { printf "Performing second pass (%s for %s)\n", $mdg->getvalue( undef, 'version' ), $mdg->getvalue( undef, 'arch' ) unless ($nooutput); $mdg->populate_all_medias(); $mdg->generate_base_files(); $mdg->push_temp_files(); $mdg->link_index_to_distrib(); $mdg->rebuild_md5(); $mdg->set_all_medias_size(); $mdg->write_mediacfg(); $mdg->write_hdlists(); $mdg->write_productid(); $mdg->write_version(); } else { print "No media change, end\n" unless ($nooutput); } if ($mustdie) { exit(0); } } __END__ =head1 DESCRIPTION F is a tool that helps to generate the structure of a Mandriva RPM repository, compatible with Mandriva tools (F, F, etc.) =head2 General Structure of a Repository A typical repository, under a root directory F, has the following structure: ROOT/ - media/ |- contrib/ | `- media_info/ |- main/ | `- media_info/ `- media_info/ In this example, we have two media, called I
and I. The RPMs packages are placed in the F
and F subdirectories. Repository metadata is contained in the top-level F directory. Per-media metadata are contained in the F
and F subdirectories. =head2 Configuration of the distribution tree Before using F, you must create a file F to describe your repository. (An empty file will work, but this isn't recommended.) The syntax of this file is reminiscent of F<.ini> files. A first section C<[media_info]> contains global information about the repository: [media_info] version=2006.0 branch=Cooker arch=i586 Then, supply one section per media. [main] hdlist=hdlist_main.cz name=Main Here, the C parameter specifies what will be the name of the hdlist file in the top-level F directory. C is a human readable label for the media. =head2 Operation F should be passed the F directory as parameter. It will then generate the hdlist and synthesis files and all other files needed for proper repository operation. F will also verify any broken dependencies in your repository and report them. =head1 SEE ALSO genhdlist(1), and MDV::Distribconf(3) for description of the format of the F file. =head1 COPYRIGHT Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 MandrakeSoft SA Copyright (C) 2005, 2006 Mandriva SA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =cut