#!/usr/bin/perl $::isInstall = 1; # for /root/drakx/ddebug.log use strict; #use lib qw(/usr/lib/libDrakX); use lib "../perl-install"; use standalone; use interactive; use common; use detect_devices; use partition_table; use fsedit; use fs; use any; use pkgs; use class_discard; use run_program; use modules; use modules::modules_conf; use modules::any_conf; use log; # my $in = interactive->vnew; $::isStandalone = undef; # for /tmp/ddebug.log $::build_globetrotter = 1; $::no_ugtk_init = 1; my (%options, @new_ARGV); foreach (@ARGV) { if (/^--(.*)/) { $options{$1} = 1; } else { push @new_ARGV, $_; } } my $rescue; if ($0 =~ /restore_globetrotter/) { %options = (install => 1, post => 1); $rescue = 1; } @ARGV = @new_ARGV; if (!$rescue) { die qq(\%_install_langs is not set to "all" in /etc/rpm/macros) if cat_('/etc/rpm/macros') !~ /\%_install_langs\s*all/; } my @suggestions = ( { mntpoint => "/", size => 4500 << 11, type => 0x483, ratio => 1, maxsize => 6000 << 11, fs_type => 'ext3' }, # splited / and /usr: # { mntpoint => "/", size => 250 << 11, type => 0x483, ratio => 1, maxsize => 2000 << 11 }, # { mntpoint => "/usr", size => 300 << 11, type => 0x483, ratio => 4, maxsize => 4000 << 11 }, { mntpoint => "/home", size => 2000 << 11, type => 0x483, ratio => 3, fs_type => 'ext3' }, # share partition with windows: { mntpoint => "/mnt/share", size => 2000 << 11, type => 0xb, ratio => 3, fs_type => 'vfat' }, { mntpoint => "/mnt/packages", size => 5000 << 11, type => 0x483, ratio => 3, maxsize => 5000 << 11, fs_type => 'ext3' }, # allocated last b/c end of disk is usually faster: { mntpoint => "swap", size => 64 << 11, type => 0x82, ratio => 1, maxsize => 500 << 11, fs_type => 'swap' }, ); sub get_hds() { my $all_hds = fsedit::get_hds(); my $other; ($all_hds->{hds}, $other) = partition { $_->{usb_description} =~ /^LaCie|LaCie Hard( |)Drive USB/ } @{$all_hds->{hds}}; my_exit("Your disk cannot be restored because it cannot be found!") if !$all_hds->{hds}[0]; $all_hds, $all_hds->{hds}[0]; # $other } sub prepare_disk() { # repartion the hard disk: print "PARTITIONNING\n"; my ($all_hds, $hd, $other) = get_hds(); # partition_table::remove($hd, $_) while partition_table::get_normal_parts($hd); run_program::run("swapoff", "/dev/$all_hds->{hds}[0]{device}8") if any { /$all_hds->{hds}[0]{device}/ } cat_("/proc/partitions"); partition_table::raw::zero_MBR_and_dirty($hd); fsedit::allocatePartitions($all_hds, \@suggestions); require diskdrake::interactive; require class_discard; # diskdrake::interactive::write_partitions(class_discard->new, $_, 'skip_check_rebootNeeded') foreach (@{$all_hds->{hds}}); foreach (@{$all_hds->{hds}}) { local $::isStandalone = undef; print "WRITE PARTITION ON $_->{file}\n"; diskdrake::interactive::write_partitions(class_discard->new, $_, 'skip_check_rebootNeeded') } # partition_table::write(@{$all_hds->{hds}}); ($all_hds, $hd, $other); } sub formatdisk { my ($hd) = @_; print "FORMATTING\n"; foreach (partition_table::get_normal_parts($hd)) { print qq(Formatting "$_->{device}" ($_->{mntpoint})\n); require fs::format; fs::format::part(undef, $_, $::prefix, undef) if !$::testing; } } #@ARGV <= 1 or die "usage: make_live [live_location=/tmp/live_tree]\n"; if (!find { m!/proc/bus/usb! } run_program::get_stdout('mount')) { warn "USB service is *NOT* started" if !$rescue; run_program::get_stdout('service', 'usb', 'start'); } sub my_exit { my ($msg) = @_; print "\n\n==============================================================\n\n"; print $msg; print "\n\nPress to return back to menu\n\n"; print "==============================================================\n\n"; ; c::_exit(0); } sub find_partition { my ($label, @parts) = @_; find { member(fs::type2fs($_), qw(ext2 ext3)) && chomp_(`e2label /dev/$_->{device} 2>/dev/root`) eq $label } @parts; } my $pkg_dev; if ($rescue) { system("mount -t tmpfs none /tmp"); # let be able to see USB devices: system("mount -t usbfs none /proc/bus/usb"); system("modprobe usb-storage; modprobe sd_mod"); # let be able to detect SCSI hds: mkdir("/sys"); system("mount -t sysfs none /sys"); my ($all_hds, $hd, $other) = get_hds(); print "Looking for the package partition\n"; my @parts = partition_table::get_normal_parts($hd); $pkg_dev = find_partition("MDK-PKGS", @parts); #die "I cannot find the package partition which is needed in order to restore the system!" my_exit("Your disk cannot be restored because there is no more a restore partition!") if is_empty_hash_ref($pkg_dev) || !$pkg_dev->{device}; print "Packages partition was found on $pkg_dev->{device}\n"; my $root = find_partition("MDK-ROOT", @parts); $root = find { $_->{device} eq "sda1" } @parts if is_empty_hash_ref($root); #my_exit("I cannot find any hard disk to restore!") if is_empty_hash_ref($root) || !$root->{device}; my_exit("Your disk cannot be restored because there is no more a root partition!") if is_empty_hash_ref($root) || !$root->{device}; print "\nPlease wait, disk is being checked, this can take quite some time\n\n"; run_program::run("e2fsck -C0 -y $_") foreach map { my $p = find_partition($_, @parts); if_($p, $p->{device}); # handle lost labels } "MDK-PKGS", "MDK-HOME"; # MDK-ROOT" print "Please wait, disk reinstallation is in progress, this can take quite some time\n"; print "Formating $root->{device}\n"; system("mkfs.ext2 -j /dev/$root->{device} > /dev/null\n"); run_program::run('tune2fs', '-L', "MDK-ROOT", "/dev/$root->{device}"); # prevent lost label if restore aborts before the end } sub installPackages() { local $::testing = undef; # for a gconftool-2 cleaner: my $pid = fork(); !defined $pid and die("cannot fork: $!"); !$pid and do { while (1) { sleep(10); run_program::run('/usr/bin/killall', 'gconftool-2') if -x '/usr/bin/killall'; } }; my $_b = before_leaving { kill 'TERM', $pid if $pid }; # ensure no %_install_langs: output_p("$::prefix/etc/rpm/macros", "%_install_langs all\n"); # ensure boot from USB will work: output_p("$::prefix/etc/sysconfig/mkinitrd", "forceusb=yes\n"); # help DrakX: mkdir_p("$::prefix/$_") foreach qw(tmp/headers var/lib/rpm root/drakx); # help packages' post scripts: mkdir_p("$::prefix/proc"); run_program::run('mount', '-t', 'proc', 'none', "$::prefix/proc"); run_program::run('makedev', "$::prefix/dev"); undef *install_any::setDefaultPackages; *install_any::setDefaultPackages = sub {}; undef *install_any::getFile; *install_any::getFile = sub { my ($f, $o_method) = @_; log::l("getFile $f:$o_method"); open(my $F, '/export/' . install_any::relGetFile($f)) or return; $F; }; undef *c::kernel_version; *c::kernel_version = sub { #my @l = glob_('/export/Mandrake/RPMS/kernel-enterprise-2.6*'); my @l = glob_('/export/media/main/kernel-2.6.*'); @l >= 1 or die "can't find kernel"; @l <= 1 or warn "too many kernels"; first(`rpm -qp --qf '%{name}' $l[-1]` =~ /kernel-(.*)/); }; my $kernel_version = c::kernel_version(); # for third party drivers: my $dkms_kernel_version = $kernel_version; $dkms_kernel_version =~ s/\.(\d*mdk)$/-$1/; print "INSTALLING\n"; install_any::setPackages(my $o = $::o = bless { prefix => $::prefix, meta_class => 'desktop', modules_conf => modules::modules_conf::read(modules::any_conf::vnew(), '/tmp/modules.conf'), default_packages => [ #- for screenshots: qw(fb2png), qw(xorg-x11-server xorg-x11-xfs xorg-x11-FBDev), qw(openssh-server), #- fred wants it qw(alsa-utils cdialog newt), qw(k3b-dvd), qw(davfs nfs-utils samba-server sane-backends xsane xsane-gimp ntp), qw(acpi acpid), #- so that removing acpi=ht will work qw(mountloop), #- crypted folders #- doc: (map { "mandrake-doc-$_" } map { ("Drakxtools-Guide-$_", "Command-Line-$_", "Quick-Startup-Plus-$_", "Starter-$_") } qw(de en es fr it)), qw(autologin grub), qw(synaptics), #- network conf: qw(wireless-tools pcmcia-cs), #- zeroconf: qw(zcip dhcpcd tmdns), #- cnx stuff: qw(dhcp-client ppp kdenetwork-kppp ppp-pppoatm ppp-pppoe pptp-linux pptp-adsl rp-pppoe), "kernel-$kernel_version", #- for older machines: "kernel-i586-up-1GB-$kernel_version", #- ISDN stuff: # qw(isdn4net ibod isdn4k-utils), # not installed since it provides an interface (will be automatically installed by drakconnect) #- network file sharing: qw(nfs-utils-clients samba-client), #- network drivers and firmwares: qw(eagle-usb ipw2100-firmware ipw2200-firmware ndiswrapper speedtouch speedtouch_mgmt unicorn), #- configuration: qw(drakconf drakcronat drakfirsttime drakxtools harddrake-ui mdkonline rpmdrake userdrake), qw(cups cups-drivers foomatic-db gimpprint hpoj libnet-snmp mtools mtoolsfm nmap printer-filters printer-testpages printer-utils scli xojpanel xpp), #- printer stuff #qw(gcc), "ati-kernel-$dkms_kernel_version", "nvidia-kernel-$dkms_kernel_version", qw(ati nvidia dkms patch dkms-ati dkms-nvidia libMesaGLU1), # qw(hcfpcimodem hsflinmodem ltmodem), #- 2.4.x only qw(xinput), #- for some mice qw(bash-completion binutils emacs-X11 ntsysv perl-doc perl-Term-Readline-Gnu vim-enhanced openssh-clients lftp diffstat), #- allow debugging qw(openssh-askpass-gnome), #- openssh-askpass for mountloop doesn't allow to click on ok/cancel buttons qw(clanbomber freeciv-client freeciv-server crack-attack kdegames), #- more games qw(numlock), # shorewall # not installed since its default config breaks network (will be automatically installed by drakfirewall) qw(xawtv zapping kdetv), #- tv apps #- locales: qw(scim-han#!/usr/bin/perl # DiskDrake # Copyright (C) 1999-2004 MandrakeSoft (pixel@mandrakesoft.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. # DiskDrake uses resize_fat which is a perl rewrite of the work of Andrew # Clausen (libresize). # DiskDrake is also based upon the libfdisk and the install from Red Hat Software use lib qw(/usr/lib/libDrakX); use standalone; #- warning, standalone must be loaded very first, for 'explanations' use common; use interactive; use detect_devices; use fsedit; use fs; use log; use c; my %options; my @l = @ARGV; while (my $e = shift @l) { my ($option) = $e =~ /--?(.*)/ or next; if ($option =~ /(.*?)=(.*)/) { $options{$1} = $2; } else { $options{$option} = ''; } } my @types = qw(hd nfs smb dav removable fileshare list-hd change-geometry); my ($type, $para) = ('hd', ''); foreach (@types) { if (exists $options{$_}) { $para = delete $options{$_}; $type = $_; last; } } keys %options and die "usage: diskdrake [--expert] [--testing] [--{" . join(",", @types) . "}]\n"; if ($>) { $ENV{PATH} = "/sbin:/usr/sbin:$ENV{PATH}"; } my $in = 'interactive'->vnew('su'); if ($type eq 'fileshare') { require any; any::fileshare_config($in, ''); $in->exit(0); } my $all_hds = fsedit::get_hds({}, $in); fs::get_raw_hds('', $all_hds); fs::get_info_from_fstab($all_hds, ''); fs::merge_info_from_mtab([ fsedit::get_really_all_fstab($all_hds) ]); $all_hds->{current_fstab} = fs::fstab_to_string($all_hds, ''); if ($type eq 'list-hd') { print partition_table::description($_), "\n" foreach fsedit::get_all_fstab($all_hds); } elsif ($type eq 'change-geometry') { $para =~ s|^/dev/||; my ($device, undef, $heads, $sectors) = $para =~ /(.+)=(\d+,)?(\d+),(\d+)$/ or die "usage: diskdrake --change-geometry=<device>=[<cylinders>,]<heads>,<sectors>\n"; my $hd = find { $_->{device} eq $device } @{$all_hds->{hds}}; put_in_hash($hd->{geom}, { heads => $heads, sectors => $sectors }); $hd->{isDirty} = 1; partition_table::write($hd); } elsif ($type eq 'hd') { require diskdrake::interactive; diskdrake::interactive::main($in, $all_hds, 0, '', sub { exec("drakhelp --id diskdrake") unless fork() }); } elsif ($type eq 'removable') { require diskdrake::removable; $para =~ s|^/dev/||; my ($raw_hd) = $para ? first(grep { $para eq $_->{device} } @{$all_hds->{raw_hds}}) || die "unknown removable $para\n" : $in->ask_from_listf('', '', \&diskdrake::interactive::format_raw_hd_info, $all_hds->{raw_hds}) or $in->exit(0); if (!$raw_hd->{mntpoint}) { my $mntpoint = detect_devices::suggest_mount_point($raw_hd); $raw_hd->{mntpoint} ||= find { !fsedit::has_mntpoint($_, $all_hds) } map { "/mnt/$mntpoint$_" } '', 2 .. 10; $raw_hd->{is_removable} = 1; #- force removable flag my $useSupermount = 'magicdev'; require security::level; require lang; fs::set_default_options($raw_hd, useSupermount => $useSupermount, security => security::level::get(), lang::fs_options(lang::read())); } diskdrake::removable::main($in, $all_hds, $raw_hd); } elsif ($type eq 'dav') { require diskdrake::dav; diskdrake::dav::main($in, $all_hds); } else { $in->ask_warn('', "Sorry only a gtk frontend is available") if !$in->isa('interactive::gtk'); require diskdrake::smbnfs_gtk; diskdrake::smbnfs_gtk::main($in, $all_hds, $type); } $in->exit(0); =================================================== # Building the disk: -d $::prefix or mkdir $::prefix; print "Making live in $::prefix directory.\n"; my ($all_hds, $hd, $other) = do { # here we want testing so that diskdrake still set mount points in data structure: local $::testing = !$options{partition}; prepare_disk(); }; formatdisk($hd) if $options{format}; add2hash($hd, $other); undef $::testing; my @parts = partition_table::get_normal_parts($hd); my ($root) = grep { $_->{mntpoint} eq "/" } @parts; print "Root is $root->{device}\n"; run_program::run('tune2fs', '-L', "MDK-ROOT", "/dev/$root->{device}"); # fs::mount_part($root, $::prefix); $fstab = [ fs::get::fstab($all_hds) ]; # we need to mount every fs we want to see into /etc/fstab !!! fs::mount_part($_, $::prefix) foreach sort { $a->{mntpoint} cmp $b->{mntpoint} } @$fstab; symlink("$::prefix/mnt/packages", "/export") if $rescue; eval { print "Installing packages\n"; installPackages(); } if $options{install}; print "ERROR WHILE INSTALLING PACKAGES: $@\n" if $@; log::closeLog; sub doRootSubst { my ($file) = @_; substInFile { s!/dev/$root->{device}!LABEL=MDK-ROOT!g; } $file; } #fs::merge_info_from_mtab($fstab); fs::write_fstab($all_hds, $::prefix); append_to_file("$::prefix/etc/fstab", "none /dev/pts devpts mode=0620 0 0\n", "none /proc proc defaults 0 0\n"); doRootSubst("$::prefix/etc/fstab"); my ($home) = grep { $_->{mntpoint} eq "/home" } @parts; my ($mnt_pkgs) = grep { $_->{mntpoint} eq "/mnt/packages" } @parts; run_program::run('tune2fs', '-L', "MDK-HOME", "/dev/$home->{device}") if $home; run_program::run('tune2fs', '-L', "MDK-PKGS", "/dev/$mnt_pkgs->{device}") if $mnt_pkgs; substInFile { s!defaults\s!defaults,ro ! if m!/mnt/packages!; s!defaults\s!defaults,umask=0000 ! if m!/mnt/share!; s!/dev/$home->{device}!LABEL=MDK-HOME!g; s!/dev/$mnt_pkgs->{device}!LABEL=MDK-PKGS!g; } "$::prefix/etc/fstab"; #------------------------------------------------------------------- #- Bootloader print "Configuring bootloader\n"; system("modprobe loop"); require keyboard; require bootloader; my $bootloader = { keytable => keyboard::keyboard2kmap(keyboard::lang2keyboard('fr')), bios => { '/dev/sda' => '0x80' }, }; bootloader::suggest($bootloader, $all_hds, vga_fb => 788, quiet => 1); # LILO failled to boot from SCSI: # $bootloader->{method} = 'lilo-graphic'; $bootloader->{method} = 'grub'; eval { bootloader::install($bootloader, $all_hds) }; doRootSubst("$::prefix/boot/grub/menu.lst"); run_program::rooted($::prefix, 'sh', '/boot/grub/install.sh'); # fix GRUB configuration: substInFile { # use FB by default on versionned entries so that the initial versionned entry behave like those created by /sbin/installkernel: s/$/ vga=788/ if /^kernel.*\d\.\d\.\d/; } "$::prefix/boot/grub/menu.lst"; ## disable ISDN by default (bogus isdn4net came with an enabled interface :-(): #substInFile { # s/#ONBOOT.*/ONBOOT="no"/ #} "$::prefix/etc/sysconfig/network-scripts/ifcfg-ippp0"; # print "Post install misc configuration\n"; # clean services: # cups-lpd ibod isdn4linux isdnlog)) { run_program::rooted($::prefix, '/sbin/chkconfig', '--del', $_) foreach qw(acon jserver oki4daemon); #foreach my $service (qw(acon atd cups-lpd hpoj ibod iptables isdn4linux isdnlog jserver ntpd oki4daemon shorewall tmdns)) { # run_program::rooted($::prefix, '/sbin/chkconfig', '--level', $_, $service, 'off') foreach qw(3 5); #} # probably useless: foreach my $service (qw(alsa dm harddrake hotplug sound)) { run_program::rooted($::prefix, '/sbin/chkconfig', '--level', $_, $service, 'on') foreach qw(3 5); } if ($options{post}) { #------------------------------------------------------------------- # save a few more files in profiles my $prof_cfg = "$::prefix/etc/netprofile/list"; my @files = map { chomp_($_) } cat_($prof_cfg); # do not save the whole /etc/sysconfig; push @files, (map { "/etc/X11/$_" } qw(XF86Config XF86Config-4 xorg.conf)), (map { "/etc/sysconfig/$_" } qw(keyboard harddrake2/previous_hw harddisks)), (map { "/etc/$_" } qw(modprobe.conf modprobe.devfs modprobe.preload modules modules.conf modules.devfs)), qw(/etc/asound.state /etc/fstab /etc/ld.so.conf/GL.conf /etc/shorewall/); output($prof_cfg, join("\n", sort @files)); #------------------------------------------------------------------- #- regenerate library loader and fonts cache run_program::rooted($::prefix, 'ldconfig'); any::fix_broken_alternatives(); run_program::rooted($::prefix, 'fc-cache'); #- generate cache in all directories mentioned in config file #- XFree touch("$::prefix/etc/menu/enable_simplified"); { local $ENV{LC_ALL} = 'en_US'; #- update-menus doesn't work when there is no locale (aka locale "C") #local $ENV{HOME} = '/'; #- savekdemimetypes.pl needs this otherwise it's tmp file fails run_program::rooted($::prefix, 'update-menus', '-n'); } run_program::rooted($::prefix, 'nspluginscan'); #- must be run before kbuildsycoca for the ksycoca to be flash plugin aware $ENV{HELP_BROWSER} = "kfmclient openProfile webbrowsing"; $ENV{BROWSER} = "kfmclient openProfile webbrowsing"; $ENV{DESKTOP} = "kde"; #- faster boot: foreach my $lang (lang::list_langs()) { local $ENV{LC_ALL} = lang::getLANGUAGE($lang); unlink "$::prefix/usr/share/services/ksycoca"; run_program::rooted($::prefix, 'kbuildsycoca', '--global'); rename("$::prefix/usr/share/services/ksycoca", "$::prefix/usr/share/services/ksycoca-$lang"); } symlinkf('/etc/X11/ksycoca', "$::prefix/usr/share/services/ksycoca"); } # clean gconftool-2 mess: unlink $_ foreach glob("$::prefix/core.*"); ##- Mandrake #substInFile { # s!Mandrake(l| L)inux release (\S+) \(.*\)!Mandrakelinux Nomad, powered by LaCie Mobile Hard Drive)!; #} "$::prefix/etc/mandrake-release"; # system("rsync -rvltp /export/ $::prefix/mnt/packages/") if !$rescue; unlink $_ foreach glob("$::prefix/var/lib/urpmi/*"); run_program::rooted($::prefix, 'urpmi.addmedia', '--probe-hdlist', $_, "/mnt/packages/media/$_/") foreach qw(main contrib firmwares dkms modules plugins); # for fast test replaying: run_program::rooted($::prefix, 'tar', 'cfj', '/root/etc.tar.bz2', '/etc'); my_exit($rescue ? "Your disk was succesfully restored!\nYou can now reboot your machine." : "Installation completed.");