diff options
Diffstat (limited to 'tools/draklive')
-rwxr-xr-x | tools/draklive | 764 |
1 files changed, 0 insertions, 764 deletions
diff --git a/tools/draklive b/tools/draklive deleted file mode 100755 index 49ead5e2b..000000000 --- a/tools/draklive +++ /dev/null @@ -1,764 +0,0 @@ -#!/usr/bin/perl - -# draklive $Id$ - -# Copyright (C) 2005 Mandriva -# Olivier Blin <oblin@mandriva.com> -# -# 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. - -use lib qw(/usr/lib/libDrakX); -use MDK::Common; -use list_modules; -use modules; -use run_program; -use POSIX qw(strftime); -use Cwd 'abs_path'; -use Getopt::Long; -use Pod::Usage; - -my $dir_distrib_sqfs = { - mountpoint => '/distrib', - type => 'squashfs', - source => 'distrib.sqfs', - build_from => '/', -}; -my $dir_memory = { - mountpoint => '/memory', - type => 'tmpfs', -}; - -my %predefined = ( - mounts => { - simple_union => { - root => '/union', - overlay => 'unionfs', - dirs => [ - $dir_memory, - { mountpoint => '/media' }, - ], - }, - squash_union => { - root => '/union', - overlay => 'unionfs', - dirs => [ - { - mountpoint => '/system', - type => 'loopfs', - pre_allocate => '100k', - source => 'system.loop' - }, - $dir_distrib_sqfs, - ], - }, - volatile_squash_union => { - root => '/union', - overlay => 'unionfs', - dirs => [ - $dir_memory, - $dir_distrib_sqfs, - ], - }, - multi_squash_union => { - root => '/union', - overlay => 'unionfs', - dirs => [ - $dir_memory, - { - mountpoint => '/system', - type => 'squashfs', - source => 'system.sqfs' - }, - $dir_distrib_sqfs, - ], - }, - }, - media => { - usb => { - storage => 'usb', - fs => 'vfat', - sleep => 15, - source => 'LABEL=MDVUSBROOT', - mountpoint => '/media', - }, - cdrom => { - storage => 'cdrom', - fs => 'iso9660', - source => 'LABEL=MDVCDROOT', - mountpoint => '/media', - }, - }, -); - -my %custom = ( - media => { - nfs => sub { - my ($module, $client, $source) = @_; - { - modules => [ $module ], - fs => 'nfs', - pre => "ifconfig eth0 $client up", - source => $source, - mountpoint => '/media', - }; - }, - }, -); - -sub nls_modules { - my ($live) = @_; - if_($live->{media}{fs} eq 'vfat', 'nls_cp437'), #- default FAT codepage - map { "nls_$_" } (map { "iso8859-$_" } 1..7, 9, 13..15), 'utf8'; -} - -sub fs_module { - my ($live) = @_; - $live->{media}{fs} eq 'iso9660' ? 'isofs' : $live->{media}{fs}; -} - -sub progress_start { - my ($total, $time, $o_exp_divide) = @_; - { - total => $total, - current => 0, - start_time => $time, - exp_divide => $o_exp_divide, - maxl => length($total) - $o_exp_divide, - }; -} - -sub progress_show_incr { - my ($progress, $incr, $time) = @_; - $progress->{current} += $incr; - my $elapsed_time = $time - $progress->{start_time}; - my $eta = int($elapsed_time*$progress->{total}/$progress->{current}); - printf("\r%3d%% (%$progress->{maxl}s/%-$progress->{maxl}s), %8s/%8s (ETA)", - int(100*$progress->{current}/$progress->{total}), - (map { substr($_, 0, length($_)-$progress->{exp_divide}) } $progress->{current}, $progress->{total}), - (map { strftime("%H:%M:%S", gmtime($_)) } $elapsed_time, $eta)); -} - -sub progress_end() { print "\n" } - -my $loop_number = 0; -my %loop = ( - squashfs => { - read_only => 1, - modules => [ qw(loop squashfs) ], - build => sub { - my ($dest, $root) = @_; - my $total = first(split /\s/, `du -sb $root`); - print "have to process " . int($total/1000000) . " MB\n"; - my $progress = progress_start($total, time(), 6); - open(my $OUTPUT, '-|', 'mksquashfs', $root, $dest, '-info'); - { - local $_; #- avoid outside $_ to be overwritten - while (<$OUTPUT>) { - if (/^mksquashfs: file .*, uncompressed size (\d+) bytes, (?:DUPLICATE)?$/) { - progress_show_incr($progress, $1, time()); - } - } - } - progress_end(); - }, - mount => sub { - my ($live, $dir) = @_; - my @mnt = ( - "/bin/losetup -r /dev/loop$loop_number $live->{media}{mountpoint}/$dir->{source}", - "mount -o ro -t squashfs /dev/loop$loop_number $dir->{mountpoint}"); - $loop_number++; - @mnt; - }, - }, - loopfs => { - modules => [], - create => sub { - my ($dest, $size) = @_; - run_('dd', "of=$dest", 'count=0', "seek=$size", 'bs=1k'); - run_('mke2fs', '-F', $dest); - }, - mount => sub { - my ($live, $dir) = @_; - my @mnt = ( - "losetup /dev/loop$loop_number $live->{media}{mountpoint}/$dir->{source}", - "mount -t ext2 /dev/loop$loop_number $dir->{mountpoint}"); - $loop_number++; - @mnt; - }, - }, - tmpfs => { - mount => sub { - my ($_live, $dir) = @_; - "mount -t tmpfs none $dir->{mountpoint}"; - }, - }, -); - -my %overlay = ( - unionfs => { - modules => [ qw(unionfs) ], - mount => sub { - my ($live) = @_; - #- build dirs list: "dir1=ro:dir2:ro:dir3=rw" - my $dirs = join(':', - map { "$_->{mountpoint}=" . - ($_->{type} && !$loop{$_->{type}}{read_only} ? 'rw' : 'ro'); - } @{$live->{mount}{dirs} || []}); - "mount -o dirs=$dirs -t unionfs unionfs $live->{mount}{root}"; - }, - }, -); - -my %storage = ( - cdrom => { - read_only => 1, - modules => 'disk/cdrom|hardware_raid|sata|scsi bus/usb disk/raw', - create => \&create_cdrom_master, - format => \&format_cdrom_device, - record => \&record_cdrom_master, - }, - usb => { - modules => 'bus/usb disk/raw|usb', - create => undef, - format => \&format_usb_device, - record => \&record_usb_master, - }, -); - -my %moddeps; -sub load_moddeps { - my ($root, $kernel_path) = @_; - my $get_modname = sub { first($_[0] =~ m!^$kernel_path/kernel/(?:.*/|)(.*?)\.k?o!) }; - %moddeps = (map { - my ($f, $deps) = split ':'; - my $modname = $get_modname->($f); - $modname => { full => $f, deps => [ map { $get_modname->($_) } split ' ', $deps ] }; - } cat_($root . $kernel_path . '/modules.dep')); -} -sub moddeps_closure { - my ($module) = @_; - my @deps = @{$moddeps{$module}{deps}}; - (map { moddeps_closure($_) } @deps), @deps; -} - -sub run_ { - print STDERR "running " . join(' ', @_) . "\n"; - run_program::run(@_); -} - -sub create_initrd { - my ($live) = @_; - - rm_rf($live->{initrd_tree}) if -e $live->{initrd_tree}; - - mkdir_p($live->{initrd_tree} . $_) foreach - qw(/bin /dev /lib /proc /sys), - $live->{media}{mountpoint}, - (map { $_->{mountpoint} } @{$live->{mount}{dirs} || []}), - $live->{mount}{root}; - - # cp_f($live->{system}{root} . '/sbin/nash', $live->{initrd_tree} . '/bin/'); - #- use nash from cooker for now, label support - cp_f('/sbin/nash', $live->{initrd_tree} . '/bin/'); - #- needed to mount loopbacks read-only - cp_f('/lib/tls/libc.so.6', $live->{initrd_tree} . '/lib/'); - cp_f('/lib/ld-linux.so.2', $live->{initrd_tree} . '/lib/'); - cp_f('/sbin/losetup', $live->{initrd_tree} . '/bin/'); - - if ($live->{media}{fs} eq 'nfs') { - cp_f('/sbin/ifconfig', $live->{initrd_tree} . '/bin/'); - cp_f('/bin/mount', $live->{initrd_tree} . '/bin/'); - if ($live->{debug}) { - cp_f('/bin/ping', $live->{initrd_tree} . '/bin/'); - cp_f('/lib/libresolv.so.2', $live->{initrd_tree} . '/lib/'); - } - } - if ($live->{debug}) { - cp_f('/usr/bin/strace', $live->{initrd_tree} . '/bin/'); - cp_f('/usr/bin/busybox', $live->{initrd_tree} . '/bin'); - my @l = map { /functions:/ .. /^$/ ? do { s/\s//g; split /,/ } : () } `busybox`; - shift @l; - symlink('busybox', $live->{initrd_tree} . "/bin/$_") foreach @l; - } - - require devices; - devices::make($live->{initrd_tree} . "/dev/$_") foreach - qw(console initrd null ram systty), - (map { "tty$_" } 0..5), - (map { "loop$_" } 0..7); - - load_moddeps($live->{system}{root}, "/lib/modules/" . $live->{system}{kernel}); - - my ($modules, $skipped) = partition { exists $moddeps{$_} } - uniq(map { modules::cond_mapping_24_26($_) } category2modules($storage{$live->{media}{storage}}{modules})); - my ($extra_modules, $missing) = partition { exists $moddeps{$_} } - nls_modules($live), - fs_module($live), - @{$live->{media}{modules} || []}, - (map { @{$loop{$_}{modules} || []} } uniq(map { $_->{type} } grep { $_->{type} } @{$live->{mount}{dirs} || []})), - ($live->{mount}{overlay} ? @{$overlay{$live->{mount}{overlay}}{modules} || []} : ()); - - @$missing and die "missing mandatory modules:" . join("\n", '', sort(@$missing)); - push @$modules, @$extra_modules; - - my @module_deps = uniq(map { moddeps_closure($_) } @$modules); - run_('gzip', '>', $live->{initrd_tree} . "/lib/$_.ko", '-dc', $live->{system}{root} . $moddeps{$_}{full}) - foreach @module_deps, @$modules; - - @$skipped and warn "skipped modules:" . join("\n", '', sort(@$skipped)); - - create_initrd_linuxrc($live, @module_deps, @$modules); - compress_initrd_tree($live); - add_splash($live); - $live->{copy_initrd} and cp_f($live->{boot_dir} . '/initrd.gz', $live->{copy_initrd}); -} - -sub create_initrd_linuxrc { - my ($live, @modules) = @_; - my $target = $live->{mount}{root} || $live->{media}{mountpoint}; - output_with_perm($live->{initrd_tree} . '/linuxrc', 0755, - join("\n", - "#!/bin/nash", - (map { "insmod /lib/$_.ko" } @modules), - if_($live->{media}{sleep}, "sleep $live->{media}{sleep}"), - #- required for labels - "mount -t proc none /proc", - #- required for cdrom labels - "mount -t sysfs none /sys", - if_($live->{debug}, "/bin/sh"), - if_($live->{media}{pre}, deref_array($live->{media}{pre})), - ($live->{media}{fs} eq 'nfs' ? '/bin/mount -n -o ro,nolock' : 'mount') . - ($storage{$live->{media}{storage}}{read_only} && " -o ro") . - " -t $live->{media}{fs} $live->{media}{source} $live->{media}{mountpoint}", - (map { $loop{$_->{type}}{mount}->($live, $_) } grep { $_->{type} } @{$live->{mount}{dirs} || []}), - ($live->{mount}{overlay} ? $overlay{$live->{mount}{overlay}}{mount}->($live) : ()), - "echo 0x0100 > /proc/sys/kernel/real-root-dev", - "umount /sys", - "umount /proc", - ($live->{mount}{overlay} ? - # don't move to /initrd but /live, or else the overlay will be unmounted - ("mkdir -p $target/live", "pivot_root $target $target/live") : - "pivot_root $target $target/initrd"), - if_($live->{post}, deref_array($live->{post})), - "")); -} - -#- builds $live->{boot_dir} . '/initrd.gz' -sub compress_initrd_tree { - my ($live) = @_; - - my $size = run_program::get_stdout("du -ks $live->{initrd_tree} | awk '{print \$1}'") + 250; - my $inodes = run_program::get_stdout("find $live->{initrd_tree} | wc -l") + 1250; - $size = int($size + $inodes / 10) + 1; #- 10 inodes needs 1K - my $initrd = $live->{boot_dir} . "/initrd"; - - mkdir_p($live->{boot_dir}); - run_('dd', 'if=/dev/zero', "of=$initrd", 'bs=1k', "count=$size"); - run_('mke2fs', '-q', '-m', 0, '-F', '-N', $inodes, '-s', 1, $initrd); - mkdir_p($live->{mnt}); - run_('mount', '-o', 'loop', '-t', 'ext2', $initrd, $live->{mnt}); - cp_af(glob("$live->{initrd_tree}/*"), $live->{mnt}); - rm_rf($live->{mnt} . "/lost+found"); - run_('umount', $live->{mnt}); - run_('gzip', '-f', '-9', $initrd); -} - -sub add_splash { - my ($live) = @_; - if ($live->{system}{vga_mode} && $live->{system}{splash} ne 'no') { - require bootloader; - my $initrd = "$live->{boot_dir}/initrd.gz"; - my $tmp_initrd = '/tmp/initrd.gz'; - cp_f($initrd, $live->{system}{root} . $tmp_initrd); - { - local $::prefix = $live->{system}{root}; - bootloader::add_boot_splash($tmp_initrd, $live->{system}{vga_mode}); - } - cp_f($live->{system}{root} . $tmp_initrd, $initrd); - unlink($live->{system}{root} . $tmp_initrd); - } -} - -sub build_syslinux_cfg { - my ($live) = @_; - #- fastboot is needed to avoid fsck - my $append = "fastboot splash=silent vga=$live->{system}{vga_mode}"; - qq(default live -prompt 1 -timeout 40 -display live.msg -label live - kernel vmlinuz - append initrd=initrd.gz $append -); -} - -sub install_system { - my ($live) = @_; - run_('drakx-in-chroot', - $live->{system}{repository}, - $live->{system}{root}, - if_($live->{system}{auto_install}, '--auto_install', abs_path($live->{system}{auto_install})), - if_($live->{system}{patch}, '--defcfg', abs_path($live->{system}{patch}))) - or die "unable to install system chroot"; - - run_('urpmi', - '--root', - $live->{system}{root}, - map { abs_path($_) } @{$live->{system}{rpms}}) if @{$live->{system}{rpms}}; - - #- make sure harddrake is run - #- (do it in chroot, or else Storable from the build box may write an incompatible config file) - system("chroot $live->{system}{root} " . - "perl -MStorable -e \"Storable::store({ UNKNOWN => {} }, '/etc/sysconfig/harddrake2/previous_hw')\""); - - #- interactive mode can lead to race in initscripts - #- (don't use addVarsInSh from MDK::Common, it breaks shell escapes) - substInFile { s/^PROMPT=.*/PROMPT=no/ } $live->{system}{root} . '/etc/sysconfig/init'; - - #- disable first boot wizard - output($live->{system}{root} . '/etc/sysconfig/firstboot', 'FIRSTBOOT=no'); - #- enable drakx-finish-install - output($live->{system}{root} . '/etc/sysconfig/finish-install', 'FINISH_INSTALL=yes'); - - #- preselect guest user in kdm - my $kdm_cfg = '/usr/share/config/kdm/kdmrc'; - update_gnomekderc($live->{system}{root} . $kdm_cfg, - 'X-:0-Greeter' => (PreselectUser => 'Default', DefaultUser => 'guest')) if -f $kdm_cfg; -} - -sub create_loopback_files { - my ($live) = @_; - mkdir_p($live->{images_dir}); - foreach (grep { $_->{build_from} } @{$live->{mount}{dirs} || []}) { - my $tree = $live->{system}{root} . $_->{build_from}; - my $dest = $live->{images_dir} . '/' . $_->{source}; - unlink($dest); - $loop{$_->{type}}{build}->($dest, $tree); - } - foreach (grep { $_->{pre_allocate} } @{$live->{mount}{dirs} || []}) { - my $dest = $live->{images_dir} . '/' . $_->{source}; - unlink($dest); - $loop{$_->{type}}{create}->($dest, $_->{pre_allocate}); - } -} - -sub get_media_label { - my ($live) = @_; - first($live->{media}{source} =~ /^LABEL=(.*)$/); -} - -sub get_media_device { - my ($live) = @_; - return $live->{media}{device} if $live->{media}{device}; - my $label = get_media_label($live) or return $live->{media}{source}; - my $device = chomp_(`readlink -f /dev/disk/by-label/$label`) - or die "unable to find device for /dev/disk/by-label/$label"; - $device; -} - -sub prepare_bootloader { - my ($live) = @_; - mkdir_p($live->{boot_dir}); - cp_f($live->{system}{root} . '/boot/vmlinuz-' . $live->{system}{kernel}, $live->{boot_dir} . '/vmlinuz'); - my $msg = $live->{system}{root} . '/boot/message-graphic'; - cp_f($msg, $live->{boot_dir} . '/live.msg') if -f $msg; - output($live->{boot_dir} . '/syslinux.cfg', build_syslinux_cfg($live)); -} - -sub create_cdrom_master { - my ($live, $opts) = @_; - my $label = get_media_label($live) or die "the source device must be described by a label"; - my @dest = $opts->{onthefly} ? () : ('-o', $live->{images_dir} . '/live.iso'); - run_('mkisofs', '-pad', '-l', '-R', '-J', '-v', '-v', - '-V', $label, #'-A', $application, '-p', $preparer, '-P', $publisher, - '-b', 'isolinux/isolinux.bin', - '-c', 'isolinux/boot.cat', - '-hide-rr-moved', '-no-emul-boot', - '-boot-load-size', 4, '-boot-info-table', - '-graft-points', - 'isolinux/isolinux.bin=/usr/lib/syslinux/isolinux-graphic.bin', - 'isolinux/isolinux.cfg=' . $live->{boot_dir} . '/syslinux.cfg', - (map { 'isolinux/=' . $live->{boot_dir} . '/' . $_ } qw(vmlinuz initrd.gz live.msg)), - (map { $live->{images_dir} . '/' . $_->{source} } grep { $_->{build_from} } @{$live->{mount}{dirs}}), - @dest, - ); -} - -#- $opts: onthefly : if true, the create function must output to stdout -sub create_master { - my ($live, $opts) = @_; - if (my $create = $storage{$live->{media}{storage}}{create}) { - $create->($live, $opts); - } else { - warn "not implemented yet"; - } -} - -sub format_cdrom_device { - my ($live) = @_; - run_('cdrecord', '-v', 'dev=' . $live->{media}{device}, "blank=fast"); -} - -sub format_usb_device { - my ($live) = @_; - run_('mkdosfs', $live->{media}{device}) - or die "unable to format device $live->{media}{device}"; -} - -sub format_device { - my ($live) = @_; - $live->{media}{device} or die "no device defined in media configuration"; - if (my $format = $storage{$live->{media}{storage}}{format}) { - $format->($live); - } else { - warn "not implemented yet"; - } -} - -sub record_cdrom_master { - my ($live, $opts) = @_; - $opts->{refresh_boot_only} and die "record boot isn't possible for cdrom master"; - $live->{media}{device} or die "no device defined in media configuration"; - my $src = $opts->{onthefly} ? '-' : $live->{images_dir} . '/live.iso'; - run_('cdrecord', '-v', 'dev=' . $live->{media}{device}, $src); -} - -sub record_usb_master { - my ($live, $opts) = @_; - if (my $label = $live->{media}{device} && get_media_label($live)) { - run_('mlabel', '-i', $live->{media}{device}, '::' . $label); - } - my $device = get_media_device($live) - or die "unable to find recording device (missing label? try with --device <device>)"; - mkdir_p($live->{mnt}); - run_('mount', $device, $live->{mnt}) - or die "unable to mount $device"; - cp_f(map { $live->{boot_dir} . "/$_" } qw(vmlinuz initrd.gz live.msg), $live->{mnt}); - unless ($opts->{refresh_boot_only}) { - foreach (grep { $_->{build_from} || $_->{pre_allocate} } @{$live->{mount}{dirs} || []}) { - print "copying $_->{source}\n"; - cp_f($live->{images_dir} . '/' . $_->{source}, $live->{mnt}); - } - } - run_('umount', $live->{mnt}); - #- use syslinux -s, "safe, slow and stupid" version of SYSLINUX - run_('syslinux', '-s', $device) or die "unable to run syslinux on $device"; -} - -#- $opts: onthefly : if true, the record function must read from stdin -sub record_master { - my ($live, $opts) = @_; - if (my $record = $storage{$live->{media}{storage}}{record}) { - $record->($live, $opts); - } else { - warn "not implemented yet"; - } -} - -sub record_boot { - my ($live) = @_; - record_master($live, { refresh => 1 }); -} - -sub pipe_subs { - my ($writer, $reader) = @_; - my ($r, $w) = POSIX::pipe; - if (my $pid = fork()) { - POSIX::close($w) or die "couldn't close: $!\n"; - my $stdin = POSIX::dup(0) or die "couldn't dup: $!\n"; - POSIX::dup2($r, 0) or die "couldn't dup2: $!\n"; - POSIX::close($r); - $reader->(); - POSIX::close(0) or warn "writer exited $?"; - POSIX::dup2($stdin, 0) or die "couldn't dup2: $!\n"; - waitpid($pid, 0); - } else { - POSIX::close($r) or die "couldn't close: $!\n"; - #- don't screw up reader - POSIX::dup2(POSIX::open('/dev/null', &POSIX::O_WRONLY), 2) or die "couldn't dup2: $!\n"; - POSIX::dup2($w, 1) or die "couldn't dup2: $!\n"; - POSIX::close($w); - $| = 1; #- autoflush write - exit !$writer->(); - } -} - -sub record_onthefly { - my ($live) = @_; - my $record = $storage{$live->{media}{storage}}{record}; - unless ($record) { - warn "not implemented yet"; - return; - } - if (my $create = $storage{$live->{media}{storage}}{create}) { - #- pipe creation step to recording step - pipe_subs(sub { $create->($live, { onthefly => 1 }) }, - sub { $record->($live, { onthefly => 1 }) }); - } else { - #- no creation step, record directly - $record->($live); - } -} - -sub complete_config { - my ($live) = @_; - - #- set unsupplied config dirs - $live->{workdir} ||= '/tmp/draklive'; - $live->{boot_dir} ||= $live->{workdir} . "/boot"; - $live->{initrd_tree} ||= $live->{workdir} . "/initrd"; - $live->{images_dir} ||= $live->{workdir} . "/images"; - $live->{mnt} ||= $live->{workdir} . "/mnt"; - - #- check for minimum requirements - ref $live->{media} or die "no media definition"; - ref $live->{system} or die "no system definition"; - $live->{system}{kernel} or die "no kernel has been configured"; - mkdir_p($live->{workdir}); -} - -sub clean { - my ($live) = @_; - rm_rf($_) foreach grep { -e $_ } $live->{workdir}, $live->{system}{root}; -} - -my @actions = ( - { name => 'clean', do => \&clean }, - { name => 'install', do => \&install_system }, - { name => 'initrd', do => \&create_initrd }, - { name => 'boot', do => \&prepare_bootloader }, - { name => 'loop', do => \&create_loopback_files }, - { name => 'master', do => \&create_master }, - { name => 'format', do => \&format_device }, - { name => 'record', do => \&record_master }, - { name => 'record_boot', do => \&record_boot }, - { name => 'record_onthefly', do => \&record_onthefly }, -); -my @all = qw(install initrd boot loop master); - -my %live; -GetOptions( - "help" => sub { pod2usage('-verbose' => 1) }, - "all" => sub { $_->{to_run} = 1 foreach grep { member($_->{name}, @all) } @actions }, - (map { $_->{name} => \$_->{to_run} } @actions), - "device:s" => sub { $live{media}{device} = $_[1] }, - "config:s" => sub { - my $path = $_[1]; - #- don't use do(), since it can't see lexicals in the enclosing scope - my $cfg = eval(cat_($path)) or die "unable to load $path"; - add2hash(\%live, $cfg); - print "loaded $path as config file\n"; - }, -) or pod2usage(); -unless (keys(%live)) { - warn 'no live definition'; - pod2usage(); -} -complete_config(\%live); - -require standalone; -every { !$_->{to_run} } @actions and die 'nothing to do'; -foreach (grep { $_->{to_run} } @actions) { - print qq(* entering step "$_->{name}"\n); - $_->{do}->(\%live); - print qq(* step "$_->{name}" done\n); -} - -__END__ - -=head1 NAME - -draklive - A live distribution mastering tool - -=head1 SYNOPSIS - -draklive [options] - - Options: - --help long help message - - --install install selected distribution in chroot - --initrd build initrd - --boot prepare bootloader files - --loop build compressed loopback files - --master build master image - - --all run all steps, from installation to mastering - - --clean clean installation chroot and work directory - - --device <dev> use this device for live recording (not needed - if the device already has the required label) - --format format selected device - --record record live on selected media - --record_boot record bootloader only on selected media - --record_onthefly record live by creating master from loopback files - on the fly - - --config <file> use this configuration file as live description - -Examples: - - draklive --config config/live.cfg --clean - - draklive --config config/live.cfg --all - - draklive --config config/live.cfg --record --device /dev/sdb1 - -=head1 OPTIONS - -=over 8 - -=item B<--config> - -Makes draklive use the next argument as a configuration file. -This file should contain an hash describing the live distribution, -meaning the system (chroot and boot), media (usb, cdrom, nfs), -and mount type (simple R/W union, union with squash files). - -Here's a configuration sample: - - { - system => { - root => '/chroot/live-move', - repository => '/mnt/ken/2006.0/i586', - kernel => '2.6.12-12mdk-i586-up-1GB', - auto_install => 'config/auto_inst.cfg.pl', - patch => 'config/patch-2006-live.pl', - rpms => [ - 'rpms/unionfs-kernel-2.6.12-12mdk-i586-up-1GB-1.1.1.1.20051124.1mdk-1mdk.i586.rpm' - ], - vga_mode => 788, - }, - media => $predefined{media}{usb}, - mount => $predefined{mounts}{squash_union} - }; - -=back - -=head1 DESCRIPTION - -B<draklive> builds a live distribution according to a -configuration file, creates a master image, -and optionnally installs it on a device. - -See L<http://qa.mandriva.com/twiki/bin/view/Main/DrakLive> - -=head1 AUTHOR - -Olivier Blin <oblin@mandriva.com> - -=cut |