package install_any; # $Id: install_any.pm,v 1.16 2003/10/31 14:13:23 rider Exp $ @ISA = qw(Exporter); %EXPORT_TAGS = ( all => [ qw(getNextStep spawnShell addToBeDone) ], ); @EXPORT_OK = map { @$_ } values %EXPORT_TAGS; use MDK::Common::System; use common; use run_program; use partition_table qw(:types); use partition_table_raw; use devices; use fsedit; use modules; use detect_devices; use lang; use any; use log; use fs; @needToCopy = qw( XFree86-Mach64 XFree86-S3 XFree86-S3V XFree86-SVGA XFree86-FBDev XFree86-server XFree86 XFree86-glide-module Mesa dhcpcd pump dhcpxd dhcp-client dev ppp autologin bootsplash foomatic gimp-print gimp-print-foomatic samba3-client samba3-client-cups ncpfs netcat printer-testpages cups xpp lpr ntp nvidia_glx_1.0.5328 nvidia_glx_common kernel-modules-nvidia-std-up fglrx_glx kernel-modules-fglrx-std-up ); push @needToCopy, "design-bootsplash-".$o->{design}; @needToCopyIfRequiresSatisfied = qw(); $boot_medium = 1; my $postinstall_rpms = ''; my $current_medium = $boot_medium; my $asked_medium = $boot_medium; my $cdrom = undef; sub useMedium($) { $_[0] > 1 and $::o->{method} eq 'cdrom' and setup_postinstall_rpms($::o->{prefix}, $::o->{packages}); $asked_medium eq $_[0] or log::l("selecting new medium '$_[0]'"); $asked_medium = $_[0]; } sub changeMedium($$) { my ($method, $medium) = @_; log::l("change to medium $medium for method $method (refused by default)"); 0; } sub relGetFile($) { local $_ = $_[0]; m|\.rpm$| ? "$::o->{packages}{mediums}{$asked_medium}{rpmsdir}/$_" : $_; } sub askChangeMedium($$) { my ($method, $medium) = @_; my $allow; do { eval { $allow = changeMedium($method, $medium) }; } while ($@); log::l($allow ? "accepting medium $medium" : "refusing medium $medium"); $allow; } sub errorOpeningFile($) { my ($file) = @_; $file eq 'XXX' and return; $current_medium eq $asked_medium and log::l("errorOpeningFile $file"), return; $::o->{packages}{mediums}{$asked_medium}{selected} or return; my $max = 32; if ($::o->{method} eq "cdrom") { cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image), and $cdrom = $1; return unless $cdrom; ejectCdrom($cdrom); while ($max > 0 && askChangeMedium($::o->{method}, $asked_medium)) { $current_medium = $asked_medium; eval { fs::mount($cdrom, "/tmp/image", "iso9660", 'readonly') }; my $getFile = getFile($file); $getFile && @advertising_images and copy_advertising($::o); $getFile and return $getFile; $current_medium = 'unknown'; ejectCdrom($cdrom); --$max; } } else { while ($max > 0 && askChangeMedium($::o->{method}, $asked_medium)) { $current_medium = $asked_medium; my $getFile = getFile($file); $getFile and return $getFile; $current_medium = 'unknown'; --$max; } } $::o->{packages}{mediums}{$asked_medium}{selected} = undef; $current_medium = 'unknown'; return; } sub getFile { my ($f, $method) = @_; log::l("getFile $f:$method"); my $rel = relGetFile($f); do { if ($method =~ /crypto/i) { require crypto; crypto::getFile($f); } elsif ($::o->{method} eq "ftp") { require ftp; ftp::getFile($rel); } elsif ($::o->{method} eq "http") { require http; http::getFile($rel); } else { my $f2 = "$postinstall_rpms/$f"; $f2 = "/tmp/image/$rel" unless $postinstall_rpms && -e $f2; open GETFILE, $f2 and *GETFILE; } } || errorOpeningFile($f); } sub getAndSaveFile { my ($file, $local) = @_ == 1 ? ("ALTLinux/mdkinst$_[0]", $_[0]) : @_; local *F; open F, ">$local" or return; local $/ = \ (16 * 1024); my $f = ref($file) ? $file : getFile($file) or return; local $_; while (<$f>) { syswrite F, $_ } 1; } sub setup_postinstall_rpms($$) { my ($prefix, $packages) = @_; $postinstall_rpms and return; $postinstall_rpms = "$prefix/usr/postinstall-rpm"; require pkgs; log::l("postinstall rpms directory set to $postinstall_rpms"); clean_postinstall_rpms(); mkdir_p($postinstall_rpms); my %toCopy; foreach (@needToCopy) { my $pkg = pkgs::packageByName($packages, $_); pkgs::selectPackage($packages, $pkg, 0, \%toCopy) if $pkg; } @toCopy{@needToCopyIfRequiresSatisfied} = (); my @toCopy = map { pkgs::packageByName($packages, $_) } keys %toCopy; pkgs::extractHeaders($prefix, \@toCopy, $packages->{mediums}{$boot_medium}); cp_af((map { "/tmp/image/" . relGetFile(pkgs::packageFile($_)) } @toCopy), $postinstall_rpms); log::l("copying Auto Install Floppy"); getAndSaveInstallFloppy($::o, "$postinstall_rpms/auto_install.img"); } sub clean_postinstall_rpms() { $postinstall_rpms and -d $postinstall_rpms and rm_rf($postinstall_rpms); } sub allowNVIDIA_rpms { return; } sub kernelVersion { my ($o) = @_; require pkgs; my $p = pkgs::packageByName($o->{packages}, "kernel-image-std-up"); $p ||= pkgs::packageByName($o->{packages}, "kernel22-up"); $p or die "I couldn't find the kernel package!"; pkgs::packageVersion($p) . "-std-up-" . pkgs::packageRelease($p); } sub getNextStep { my ($s) = $::o->{steps}{first}; $s = $::o->{steps}{$s}{next} while $::o->{steps}{$s}{done} || !$::o->{steps}{$s}{reachable}; $s; } sub spawnShell { return if $::o->{localInstall} || $::testing; -x "/bin/sh" or die "cannot open shell - /bin/sh doesn't exist"; fork and return; $ENV{DISPLAY} ||= ":0"; local *F; sysopen F, "/dev/tty2", 2 or die "cannot open /dev/tty2 -- no shell will be provided"; open STDIN, "<&F" or die ''; open STDOUT, ">&F" or die ''; open STDERR, ">&F" or die ''; close F; print any::drakx_version(), "\n"; c::setsid(); ioctl(STDIN, c::TIOCSCTTY(), 0) or warn "could not set new controlling tty: $!"; my $busybox = "/usr/bin/busybox"; exec {-e $busybox ? $busybox : "/bin/sh"} "/bin/sh" or log::l("exec of /bin/sh failed: $!"); } sub fsck_option { my ($o) = @_; my $y = $o->{security} < 3 && !$::expert && "-y "; substInFile { s/^(\s*fsckoptions="?)(-y )?/$1$y/ } "$o->{prefix}/etc/rc.d/rc.sysinit"; } sub getAvailableSpace { my ($o) = @_; my $minAvailableSize = 65 * sqr(1024); my $n = !$::testing && getAvailableSpace_mounted($o->{prefix}) || getAvailableSpace_raw($o->{fstab}) * 512 / 1.07; $n - max(0.1 * $n, $minAvailableSize); } sub getAvailableSpace_mounted { my ($prefix) = @_; my $dir = -d "$prefix/usr" ? "$prefix/usr" : "$prefix"; my (undef, $free) = MDK::Common::System::df($dir) or return; log::l("getAvailableSpace_mounted $free KB"); $free * 1024 || 1; } sub getAvailableSpace_raw { my ($fstab) = @_; do { $_->{mntpoint} eq '/usr' and return $_->{size} } foreach @$fstab; do { $_->{mntpoint} eq '/' and return $_->{size} } foreach @$fstab; if ($::testing) { my $nb = 450; log::l("taking ${nb}MB for testing"); return $nb << 11; } die "missing root partition"; } sub preConfigureTimezone { my ($o) = @_; require timezone; $o->{timezone}{timezone} ||= timezone::bestTimezone(lang::lang2text($o->{lang})); my $utc = $::expert && !grep { isFat($_) || isNT($_) } @{$o->{fstab}}; my $ntp = timezone::ntp_server($o->{prefix}); add2hash_($o->{timezone}, { UTC => $utc, ntp => $ntp }); } sub setPackages { my ($o) = @_; require pkgs; if (!$o->{packages} || is_empty_hash_ref($o->{packages}{names})) { $o->{packages} = pkgs::psUsingHdlists($o->{prefix}, $o->{method}); push @{$o->{default_packages}}, "glibc"; push @{$o->{default_packages}}, "glibc-locales"; push @{$o->{default_packages}}, "nfs-clients"; push @{$o->{default_packages}}, "portmap"; push @{$o->{default_packages}}, "numlock" if $o->{miscellaneous}{numlock}; push @{$o->{default_packages}}, "kernel-image-std-up", "kernel-modules-3c90x-std-up", "kernel-modules-cifs-std-up", "kernel-modules-hostap-std-up", "kernel-modules-v4l-std-up", "kernel-modules-bcm5700-std-up", "kernel-modules-drm-std-up", "kernel-modules-fglrx-std-up", "kernel-modules-hcfpcimodem-std-up", "kernel-modules-lm_sensors-std-up", "kernel-modules-madwifi-std-up", "kernel-modules-nvidia-std-up", "kernel-modules-slicoss-std-up", "kernel-modules-slmdm-std-up", if !$::oem && c::kernel_version() =~ /^\Q2.4/; push @{$o->{default_packages}}, "kernel-image-std-smp" if detect_devices::hasSMP(); push @{$o->{default_packages}}, "nvidia_glx_1.0.5328"; push @{$o->{default_packages}}, "nvidia_glx_common"; push @{$o->{default_packages}}, "raidtools" if !is_empty_array_ref($o->{all_hds}{raids}); push @{$o->{default_packages}}, "lvm" if !is_empty_array_ref($o->{all_hds}{lvms}); push @{$o->{default_packages}}, "hotplug" if modules::get_alias("usb-interface"); push @{$o->{default_packages}}, "reiserfs-utils" if grep { isThisFs("reiserfs35", $_) } @{$o->{fstab}} or grep { isThisFs("reiserfs36", $_) } @{$o->{fstab}}; push @{$o->{default_packages}}, "xfsprogs" if grep { isThisFs("xfs", $_) } @{$o->{fstab}}; push @{$o->{default_packages}}, "jfsprogs" if grep { isThisFs("jfs", $_) } @{$o->{fstab}}; push @{$o->{default_packages}}, "kernel-modules-alsa-std-up", "alsa2-utils", "aumix" if modules::get_alias("sound-slot-0") =~ /^snd-/; push @{$o->{default_packages}}, "kernel-modules-pctel-std-up" if grep { $_->{driver} =~ /^pctel/ } detect_devices::probeall(); push @{$o->{default_packages}}, "kernel-modules-nvidia-nforce-std-up" if grep { $_->{driver} eq 'nvnet' } detect_devices::probeall(); push @{$o->{default_packages}}, "hsflinmodem", "kernel-modules-hsflinmodem-std-up" if grep { $_->{driver} eq 'hsfserial' } detect_devices::probeall(); push @{$o->{default_packages}}, "kernel-modules-ltmodem-std-up" if grep { $_->{driver} eq 'lt_modem' } detect_devices::probeall(); push @{$o->{default_packages}}, "kernel-modules-slmdm-data", "kernel-modules-slmdm-std-up" if grep { $_->{driver} eq 'slamrmo' } detect_devices::probeall(); push @{$o->{default_packages}}, "kernel-modules-slmodem-std-up", "slmodemd" if grep { $_->{driver} eq 'slamr' } detect_devices::probeall(); pkgs::getDeps($o->{prefix}, $o->{packages}); pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, 'basesystem') || die("missing basesystem package"), 1); pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, 'interactivesystem') || die("missing interactivesystem package"), 1); pkgs::getProvides($o->{packages}); pkgs::read_rpmsrate($o->{packages}, getFile("ALTLinux/base/rpmsrate")); ($o->{compssUsers}, $o->{compssUsersSorted}) = pkgs::readCompssUsers($o->{meta_class}); if ($::auto_install && $o->{compssUsersChoice}{ALL}) { $o->{compssUsersChoice}{$_} = 1 foreach map { @{$o->{compssUsers}{$_}{flags}} } @{$o->{compssUsersSorted}}; } if (!$o->{compssUsersChoice} && !$o->{isUpgrade}) { $o->{compssUsersChoice}{$_} = 1 foreach 'GNOME', 'KDE', 'CONFIG', 'X', 'ICEWM', 'WMAKER'; $o->{compssUsersChoice}{$_} = 1 foreach map { @{$o->{compssUsers}{$_}{flags}} } 'Workstation|Office Workstation', 'Workstation|Internet station', 'Workstation|Configuration', 'Workstation|Multimedia station', 'Workstation|Utilities', 'Networking services|FTP/Mail', 'Networking services|DNS', 'Networking services|Firewall/Router', 'Networking services|Network Computer server', 'Games|Games', 'Games|3D Games'; } $o->{compssUsersChoice}{uc($_)} = 1 foreach grep { modules::get_that_type($_) } ('tv', 'scanner', 'photo', 'sound'); $o->{compssUsersChoice}{uc($_)} = 1 foreach map { $_->{driver} =~ /Flag:(.*)/ } detect_devices::probeall(); $o->{compssUsersChoice}{SYSTEM} = 1; $o->{compssUsersChoice}{BURNER} = 1 if detect_devices::burners(); $o->{compssUsersChoice}{DVD} = 1 if detect_devices::dvdroms(); $o->{compssUsersChoice}{PCMCIA} = 1 if detect_devices::hasPCMCIA(); $o->{compssUsersChoice}{HIGH_SECURITY} = 1 if $o->{security} > 3; $o->{compssUsersChoice}{'3D'} = 1 if detect_devices::matching_desc('Matrox.* G[245][05]0') || detect_devices::matching_desc('Riva.*128') || detect_devices::matching_desc('Rage X[CL]') || detect_devices::matching_desc('Rage Mobility [PL]') || detect_devices::matching_desc('3D Rage (?:LT|Pro)') || detect_devices::matching_desc('Intel') || detect_devices::matching_desc('Voodoo [35]') || detect_devices::matching_desc('Voodoo Banshee') || detect_devices::matching_desc('8281[05].* CGC') || detect_devices::matching_desc('82845.* CGC') || detect_devices::matching_desc('Rage 128') || detect_devices::matching_desc('Radeon ') || detect_devices::matching_desc('[nN]Vidia.*T[nN]T2') || detect_devices::matching_desc('[nN]Vidia.*NV[56]') || detect_devices::matching_desc('[nN]Vidia.*Vanta') || detect_devices::matching_desc('[nN]Vidia.*GeForce') || detect_devices::matching_desc('[nN]Vidia.*NV1[15]') || detect_devices::matching_desc('[nN]Vidia.*Quadro'); foreach (map { substr($_, 0, 2) } lang::langs($o->{langs})) { pkgs::packageByName($o->{packages}, "locales-$_") or next; $o->{compssUsersChoice}{qq(LOCALES"$_")} = 1; } foreach (map { substr($_, 0, 2) } lang::langs($o->{langs})) { $o->{compssUsersChoice}{qq(LOCALES"$_")} = 1; } foreach ( lang::langs($o->{langs}) ){ $o->{compssUsersChoice}{'CHARSET"' . lang::lang2charset($_) . '"'} = 1; } } else { pkgs::psUpdateHdlistsDeps($o->{prefix}, $o->{method}); } } sub unselectMostPackages { my ($o) = @_; pkgs::unselectAllPackages($o->{packages}); pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, $_) || next) foreach @{$o->{default_packages}}; } sub warnAboutNaughtyServers { my ($o) = @_; return 1; my @naughtyServers = pkgs::naughtyServers($o->{packages}) or return 1; if (!$o->ask_yesorno('', formatAlaTeX(_("You have selected the following server(s): %s These servers are activated by default. They don't have any known security issues, but some new could be found. In that case, you must make sure to upgrade as soon as possible. Do you really want to install these servers? ", join(", ", @naughtyServers))), 1)) { pkgs::unselectPackage($o->{packages}, pkgs::packageByName($o->{packages}, $_)) foreach @naughtyServers; } } sub addToBeDone(&$) { my ($f, $step) = @_; return &$f() if $::o->{steps}{$step}{done}; push @{$::o->{steps}{$step}{toBeDone}}, $f; } sub killCardServices { my $pid = chomp_(cat_("/tmp/cardmgr.pid")); $pid and kill(15, $pid); } sub unlockCdrom(;$) { my ($cdrom) = @_; $cdrom or cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image), and $cdrom = $1; eval { $cdrom and ioctl detect_devices::tryOpen($1), c::CDROM_LOCKDOOR(), 0 }; } sub ejectCdrom(;$) { my ($cdrom) = @_; getFile("XXX"); $cdrom ||= $1 if cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image),; if ($cdrom) { eval { fs::umount("/tmp/image") }; eval { ioctl detect_devices::tryOpen($cdrom), c::CDROMEJECT(), 1 }; } } sub setupFB { my ($o, $vga) = @_; $vga ||= 785; require bootloader; foreach (qw(vmlinuz-up vmlinuz-smp )) { if (my $e = bootloader::get("/boot/$_", $o->{bootloader})) { $e->{vga} = $vga; } } bootloader::install($o->{prefix}, $o->{bootloader}, $o->{fstab}, $o->{all_hds}{hds}); 1; } sub hdInstallPath() { my $tail = first(readlink("/tmp/image") =~ m|^/tmp/hdimage/(.*)|); my $head = first(readlink("/tmp/hdimage") =~ m|$::o->{prefix}(.*)|); $tail && ($head ? "$head/$tail" : "/mnt/hd/$tail"); } sub install_urpmi { my ($prefix, $method, $mediums) = @_; $method eq 'disk' && !hdInstallPath() and return; my @cfg = map_index { my $name = $_->{fakemedium}; run_program::rooted($prefix, "parsehdlist", ">", "/var/lib/urpmi/synthesis.hdlist.$name", "--compact", "--provides", "--requires", "/var/lib/urpmi/hdlist.$name.cz"); run_program::rooted($prefix, "gzip", "-S", ".cz", "/var/lib/urpmi/synthesis.hdlist.$name"); -s "$prefix/var/lib/urpmi/synthesis.hdlist.$name.cz" > 24 or unlink "$prefix/var/lib/urpmi/synthesis.hdlist.$name.cz"; local *LIST; my $mask = umask 077; open LIST, ">$prefix/var/lib/urpmi/list.$name" or log::l("failed to write list.$name"); umask $mask; my $dir = ${{ nfs => "file://mnt/nfs", disk => "file:/" . hdInstallPath(), ftp => $ENV{URLPREFIX}, http => $ENV{URLPREFIX}, cdrom => "removable_cdrom://mnt/cdrom" }}{$method} . "/$_->{rpmsdir}"; local *FILES; open FILES, "$ENV{LD_LOADER} parsehdlist /tmp/$_->{hdlist} |"; print LIST "$dir/$_\n" foreach chomp_(); close FILES or log::l("parsehdlist failed"), return; close LIST; my ($qname, $qdir) = ($name, $dir); $qname =~ s/(\s)/\\$1/g; $qdir =~ s/(\s)/\\$1/g; "$qname " . ($dir !~ /^(ftp|http)/ && $qdir) . " { hdlist: hdlist.$name.cz with_hdlist: ../base/$_->{hdlist} list: list.$name" . ($dir =~ /removable_([^\s:_]*)/ && " removable: /dev/$1") . " } "; } values %$mediums; eval { output "$prefix/etc/urpmi/urpmi.cfg", @cfg }; } sub auto_inst_file() { ($::g_auto_install ? "/tmp" : "$::o->{prefix}/root") . "/auto_inst.cfg.pl" } sub report_bug { my ($prefix) = @_; any::report_bug($prefix, 'auto_inst' => g_auto_install()); } sub g_auto_install { my ($replay) = @_; my $o = {}; require pkgs; $o->{default_packages} = pkgs::selected_leaves($::o->{packages}); my @fields = qw(mntpoint type size); $o->{partitions} = [ map { my %l; @l{@fields} = @$_{@fields}; \%l } grep { $_->{mntpoint} } @{$::o->{fstab}} ]; exists $::o->{$_} and $o->{$_} = $::o->{$_} foreach qw(lang authentication mouse wacom netc timezone superuser intf keyboard users partitioning isUpgrade manualFstab nomouseprobe crypto security netcnx useSupermount autoExitInstall mkbootdisk); if (my $printer = $::o->{printer}) { $o->{printer}{$_} = $::o->{printer}{$_} foreach qw(SPOOLER DEFAULT BROWSEPOLLADDR BROWSEPOLLPORT MANUALCUPSCONFIG); $o->{printer}{configured} = {}; foreach my $queue (keys %{$::o->{printer}{configured}}) { my $val = $::o->{printer}{configured}{$queue}{queuedata}; exists $val->{$_} and $o->{printer}{configured}{$queue}{queuedata}{$_} = $val->{$_} foreach keys %{$val || {}}; } } if (my $card = $::o->{X}{card}) { $o->{X}{$_} = $::o->{X}{$_} foreach qw(default_depth resolution_wanted); if ($o->{X}{default_depth} and my $depth = $card->{depth}{$o->{X}{default_depth}}) { $depth ||= []; $o->{X}{resolution_wanted} ||= join "x", @{$depth->[0]} unless is_empty_array_ref($depth->[0]); $o->{X}{monitor} = $::o->{X}{monitor} if $::o->{X}{monitor}{manual}; } } local $o->{partitioning}{auto_allocate} = !$replay; local $o->{autoExitInstall} = !$replay; $o->{users} = [ @{$o->{users} || []} ]; $_ = { %{$_ || {}} }, delete @$_{qw(oldu oldg password password2)} foreach $o->{superuser}, @{$o->{users} || []}; require Data::Dumper; my $str = join('', "#!/usr/bin/perl -cw # # You should check the syntax of this file before using it in an auto-install. # You can do this with 'perl -cw auto_inst.cfg.pl' or by executing this file # (note the '#!/usr/bin/perl -cw' on the first line). ", Data::Dumper->Dump([$o], ['$o']), if_($replay, qq(\npackage install_steps_auto_install;), q( $graphical = 1; push @graphical_steps, 'doPartitionDisks', 'formatPartitions'; )), "\0"); $str =~ s/ {8}/\t/g; $str; } sub getAndSaveInstallFloppy { my ($o, $where) = @_; if ($postinstall_rpms && -d $postinstall_rpms && -r "$postinstall_rpms/auto_install.img") { log::l("getAndSaveInstallFloppy: using file saved as $postinstall_rpms/auto_install.img"); cp_af("$postinstall_rpms/auto_install.img", $where); } else { my $image = cat_("/proc/cmdline") =~ /pcmcia/ ? "pcmcia" : ${{ disk => 'hd', cdrom => 'cdrom', ftp => 'network', nfs => 'network', http => 'network' }}{$o->{method}}; $image .= arch() =~ /sparc64/ && "64"; getAndSaveFile("images/$image.img", $where) or log::l("failed to write Install Floppy ($image.img) to $where"), return; } 1; } sub getAndSaveAutoInstallFloppy { my ($o, $replay, $where) = @_; eval { modules::load('loop') }; if (arch() =~ /sparc/) { my $imagefile = "$o->{prefix}/tmp/autoinst.img"; my $mountdir = "$o->{prefix}/tmp/mount"; -d $mountdir or mkdir $mountdir, 0755; my $workdir = "$o->{prefix}/tmp/work"; -d $workdir or rmdir $workdir; getAndSaveInstallFloppy($o, $imagefile) or return; devices::make($_) foreach qw(/dev/loop6 /dev/ram); run_program::run("losetup", "/dev/loop6", $imagefile); fs::mount("/dev/loop6", $mountdir, "romfs", 'readonly'); cp_af($mountdir, $workdir); fs::umount($mountdir); run_program::run("losetup", "-d", "/dev/loop6"); substInFile { s/timeout.*//; s/^(\s*append\s*=\s*\".*)\"/$1 kickstart=floppy\"/ } "$workdir/silo.conf"; #" for po output "$workdir/boot.msg", "\n7m", "!! If you press enter, an auto-install is going to start. ALL data on this computer is going to be lost, including any Windows partitions !! ", "7m\n"; local $o->{partitioning}{clearall} = 1; output("$workdir/auto_inst.cfg", g_auto_install()); run_program::run("genromfs", "-d", $workdir, "-f", "/dev/ram", "-A", "2048,/..", "-a", "512", "-V", "DrakX autoinst"); fs::mount("/dev/ram", $mountdir, 'romfs', 0); run_program::run("silo", "-r", $mountdir, "-F", "-i", "/fd.b", "-b", "/second.b", "-C", "/silo.conf"); fs::umount($mountdir); require commands; commands::dd("if=/dev/ram", "of=$where", "bs=1440", "count=1024"); rm_rf($workdir, $mountdir, $imagefile); } elsif (arch() =~ /ia64/) { } else { my $imagefile = "$o->{prefix}/tmp/autoinst.img"; my $mountdir = "$o->{prefix}/tmp/aif-mount"; -d $mountdir or mkdir $mountdir, 0755; my $param = 'kickstart=floppy ' . generate_automatic_stage1_params($o); getAndSaveInstallFloppy($o, $imagefile) or return; my $dev = devices::set_loop($imagefile) or log::l("couldn't set loopback device"), return; fs::mount($dev, $mountdir, 'vfat', 0); substInFile { s/timeout.*/$replay ? 'timeout 1' : ''/e; s/^(\s*append)/$1 $param/ } "$mountdir/syslinux.cfg"; unlink "$mountdir/help.msg"; output "$mountdir/boot.msg", "\n0c", "!! If you press enter, an auto-install is going to start. All data on this computer is going to be lost, including any Windows partitions !! ", "07\n" if !$replay; local $o->{partitioning}{clearall} = !$replay; output("$mountdir/auto_inst.cfg", g_auto_install($replay)); fs::umount($mountdir); rmdir $mountdir; c::del_loop($dev); require commands; commands::dd("if=$imagefile", "of=$where", "bs=1440", "count=1024"); unlink $imagefile; } 1; } sub g_default_packages { my ($o, $quiet) = @_; my $floppy = detect_devices::floppy(); while (1) { $o->ask_okcancel('', _("Insert a FAT formatted floppy in drive %s", $floppy), 1) or return; eval { fs::mount(devices::make($floppy), "/floppy", "vfat", 0) }; last if !$@; $o->ask_warn('', _("This floppy is not FAT formatted")); } require Data::Dumper; my $str = Data::Dumper->Dump([ { default_packages => pkgs::selected_leaves($o->{packages}) } ], ['$o']); $str =~ s/ {8}/\t/g; output('/floppy/auto_inst.cfg', "# You should always check the syntax with 'perl -cw auto_inst.cfg.pl'\n", "# before testing. To use it, boot with ``linux defcfg=floppy''\n", $str, "\0"); fs::umount("/floppy"); $quiet or $o->ask_warn('', _("To use this saved packages selection, boot installation with ``linux defcfg=floppy''")); } sub loadO { my ($O, $f) = @_; $f ||= auto_inst_file; my $o; if ($f =~ /^(floppy|patch)$/) { my $f = $f eq "floppy" ? 'auto_inst.cfg' : "patch"; unless ($::testing) { fs::mount(devices::make(detect_devices::floppy()), "/mnt", (arch() =~ /sparc/ ? "romfs" : "vfat"), 'readonly'); $f = "/mnt/$f"; } -e $f or $f .= '.pl'; my $b = before_leaving { fs::umount("/mnt") unless $::testing; modules::unload($_) foreach qw(vfat fat); }; $o = loadO($O, $f); } else { -e "$f.pl" and $f .= ".pl" unless -e $f; my $fh = -e $f ? do { local *F; open F, $f; *F } : getFile($f) or die _("Error reading file %s", $f); { local $/ = "\0"; no strict; eval <$fh>; close $fh; $@ and die; } add2hash_($o ||= {}, $O); } bless $o, ref $O; } sub generate_automatic_stage1_params { my ($o) = @_; my @ks = "method:$o->{method}"; if ($o->{method} =~ /http/) { "$ENV{URLPREFIX}" =~ m|http://(.*)/(.*)| or die; push @ks, "server:$1", "directory:$2"; } elsif ($o->{method} =~ /ftp/) { push @ks, "server:$ENV{HOST}", "directory:$ENV{PREFIX}", "user:$ENV{LOGIN}", "pass:$ENV{PASSWORD}"; } elsif ($o->{method} =~ /nfs/) { cat_("/proc/mounts") =~ m|(\S+):(\S+)\s+/tmp/image nfs| or die; push @ks, "server:$1", "directory:$2"; } my ($intf) = values %{$o->{intf}}; if ($intf->{BOOTPROTO} =~ /dhcp/) { push @ks, "network:dhcp"; } else { require network; push @ks, "network:static", "ip:$intf->{IPADDR}", "netmask:$intf->{NETMASK}", "gateway:$o->{netc}{GATEWAY}"; my @dnss = network::dnsServers($o->{netc}); push @ks, "dns:$dnss[0]" if @dnss; } "automatic=".join(',', @ks); } sub guess_mount_point { my ($part, $prefix, $user) = @_; my %l = ( '/' => 'etc/fstab', '/boot' => 'vmlinuz', '/tmp' => '.X11-unix', '/usr' => 'X11R6', '/var' => 'catman', ); my $handle = any::inspect($part, $prefix) or return; my $d = $handle->{dir}; my ($mnt) = grep { -e "$d/$l{$_}" } keys %l; $mnt ||= (stat("$d/.bashrc"))[4] ? '/root' : '/home/user' . ++$$user if -e "$d/.bashrc"; $mnt ||= (grep { -d $_ && (stat($_))[4] >= 500 && -e "$_/.bashrc" } glob_("$d")) ? '/home' : ''; ($mnt, $handle); } sub suggest_mount_points { my ($fstab, $prefix, $uniq) = @_; my $user; foreach my $part (grep { isTrueFS($_) } @$fstab) { $part->{mntpoint} && !$part->{unsafeMntpoint} and next; my ($mnt, $handle) = guess_mount_point($part, $prefix, \$user) or next; next if $uniq && fsedit::mntpoint2part($mnt, $fstab); $part->{mntpoint} = $mnt; delete $part->{unsafeMntpoint}; fs::merge_info_from_fstab($fstab, $handle->{dir}, $uniq) if $mnt eq '/'; } $_->{mntpoint} and log::l("suggest_mount_points: $_->{device} -> $_->{mntpoint}") foreach @$fstab; } sub find_root_parts { my ($fstab, $prefix) = @_; log::l("find_root_parts"); my $user; grep { my ($mnt) = guess_mount_point($_, $prefix, \$user); $mnt eq '/'; } @$fstab; } sub use_root_part { my ($fstab, $part, $prefix) = @_; { my $handle = any::inspect($part, $prefix) or die; fs::merge_info_from_fstab($fstab, $handle->{dir}, 'uniq'); } map { $_->{mntpoint} = 'swap' } grep { isSwap($_) } @$fstab; } sub getHds { my ($o, $f_err) = @_; my $ok = 1; my $try_scsi = !$::expert; my $flags = $o->{partitioning}; my @drives = detect_devices::hds(); # add2hash_($o->{partitioning}, { readonly => 1 }) if partition_table_raw::typeOfMBR($drives[0]{device}) eq 'system_commander'; getHds: my $all_hds = catch_cdie { fsedit::hds(\@drives, $flags) } sub { $ok = 0; my $err = $@; $err =~ s/ at (.*?)$//; log::l("error reading partition table: $err"); !$flags->{readonly} && $f_err and $f_err->($err); }; my $hds = $all_hds->{hds}; if (is_empty_array_ref($hds) && $try_scsi) { $try_scsi = 0; $o->setupSCSI; goto getHds; } if (!$::testing) { @$hds = grep { eval { partition_table_raw::test_for_bad_drives($_) }; !$@ } @$hds; } $ok = fsedit::verifyHds($hds, $flags->{readonly}, $ok) if !($flags->{clearall} || $flags->{clear}); $ok && $hds && @$hds > 0 && @{$o->{all_hds}{hds} || []} == @$hds and return $ok; fs::get_raw_hds('', $all_hds); fs::add2all_hds($all_hds, @{$o->{manualFstab}}); $o->{all_hds} = $all_hds; $o->{fstab} = [ fsedit::get_all_fstab($all_hds) ]; fs::merge_info_from_mtab($o->{fstab}); my @win = grep { isFat($_) && isFat({ type => fsedit::typeOfPart($_->{device}) }) } @{$o->{fstab}}; log::l("win parts: ", join ",", map { $_->{device} } @win) if @win; if (@win == 1) { $win[0]{mntpoint} = arch() =~ /ia64/ ? "/boot/efi" : "/mnt/windows"; } else { my %w; foreach (@win) { my $v = $w{$_->{device_windobe}}++; $_->{mntpoint} = $_->{unsafeMntpoint} = "/mnt/win_" . lc($_->{device_windobe}) . ($v ? $v+1 : ''); } } my @sunos = grep { isSunOS($_) && type2name($_->{type}) =~ /root/i } @{$o->{fstab}}; if (@sunos) { my $v = ''; map { $_->{mntpoint} = $_->{unsafeMntpoint} = "/mnt/sunos" . ($v && ++$v) } @sunos; } $ok; } sub log_sizes { my ($o) = @_; my @df = MDK::Common::System::df($o->{prefix}); log::l(sprintf "Installed: %s(df), %s(rpm)", formatXiB($df[0] - $df[1], 1024), formatXiB(sum(`$ENV{LD_LOADER} rpm --root $o->{prefix}/ -qa --queryformat "%{size}\n"`))) if -x "$o->{prefix}/bin/rpm"; } sub copy_advertising { my ($o) = @_; return if $::rootwidth < 800; my $f; my $source_dir = "ALTLinux/share/advertising"; foreach ("." . $o->{lang}, "." . substr($o->{lang},0,2), '') { $f = getFile("$source_dir$_/list") or next; $source_dir = "$source_dir$_"; } if (my @files = <$f>) { my $dir = "$o->{prefix}/tmp/drakx-images"; mkdir $dir; unlink glob_("$dir/*"); foreach (@files) { chomp; getAndSaveFile("$source_dir/$_", "$dir/$_"); } @advertising_images = map { "$dir/$_" } @files; } } sub remove_advertising { my ($o) = @_; unlink @advertising_images; rmdir "$o->{prefix}/tmp/drakx-images"; @advertising_images = (); } sub disable_user_view { my ($prefix) = @_; substInFile { s/^UserView=.*/UserView=true/ } "$prefix/usr/share/config/kdm/kdmrc"; substInFile { s/^Browser=.*/Browser=0/ } "$prefix/etc/X11/gdm/gdm.conf"; } sub write_fstab { my ($o) = @_; fs::write_fstab($o->{all_hds}, $o->{prefix}) if !$::live; } my @bigseldom_used_groups = ( [ qw(pvcreate pvdisplay vgchange vgcreate vgdisplay vgextend vgremove vgscan lvcreate lvdisplay lvremove /lib/liblvm.so) ], ); sub check_prog { my ($f) = @_; my @l = $f !~ m|^/| ? map { "$_/$f" } split(":", $ENV{PATH}) : $f; return if grep { -x $_ } @l; common::usingRamdisk() or log::l("ERROR: check_prog can't find the program $f and we're not using ramdisk"), return; my ($f_) = map { m|^/| ? $_ : "/usr/bin/$_" } $f; remove_bigseldom_used(); foreach (@bigseldom_used_groups) { my (@l) = map { m|^/| ? $_ : "/usr/bin/$_" } @$_; if (member($f_, @l)) { foreach (@l) { getAndSaveFile($_); chmod 0755, $_; } return; } } getAndSaveFile($f_); chmod 0755, $f_; } sub remove_unused { $::testing and return; if ($::o->isa('interactive_gtk')) { unlink glob_("/lib/lib$_*") foreach qw(slang newt); unlink "/usr/bin/perl-install/auto/Newt/Newt.so"; } else { unlink glob_("/usr/X11R6/bin/XF*"); } } sub remove_bigseldom_used { log::l("remove_bigseldom_used"); $::testing and return; remove_unused(); unlink glob_("/usr/share/gtk/themes/$_*") foreach qw(DarkMarble marble3d); unlink(m|^/| ? $_ : "/usr/bin/$_") foreach ((map { @$_ } @bigseldom_used_groups), qw(mkreiserfs-3.5.x resize_reiserfs-3.5.x), ); } ################################################################################ package pkgs_interactive; use run_program; use common; use pkgs; sub install_steps::do_pkgs { my ($o) = @_; bless { o => $o }, 'pkgs_interactive'; } sub install { my ($do, @l) = @_; $do->{o}->pkg_install(@l); } sub is_installed { my ($do, @l) = @_; foreach (@l) { my $p = pkgs::packageByName($do->{o}->{packages}, $_); $p && pkgs::packageFlagSelected($p) or return; } 1; } sub remove { my ($do, @l) = @_; @l = grep { my $p = pkgs::packageByName($do->{o}->{packages}, $_); pkgs::unselectPackage($do->{o}->{packages}, $p) if $p; $p; } @l; run_program::rooted($do->{o}->{prefix}, 'rpm', '-e', @l); } sub remove_nodeps { my ($do, @l) = @_; @l = grep { my $p = pkgs::packageByName($do->{o}->{packages}, $_); pkgs::packageSetFlagSelected($p, 0) if $p; $p; } @l; run_program::rooted($do->{o}->{prefix}, 'rpm', '-e', '--nodeps', @l); } ################################################################################ package install_any; 1;