summaryrefslogtreecommitdiffstats
path: root/pxe_wizard/drakpxe.old
diff options
context:
space:
mode:
Diffstat (limited to 'pxe_wizard/drakpxe.old')
-rwxr-xr-xpxe_wizard/drakpxe.old516
1 files changed, 516 insertions, 0 deletions
diff --git a/pxe_wizard/drakpxe.old b/pxe_wizard/drakpxe.old
new file mode 100755
index 00000000..e055b6c1
--- /dev/null
+++ b/pxe_wizard/drakpxe.old
@@ -0,0 +1,516 @@
+#!/usr/bin/perl
+#
+# François Pons <fpons@mandrakesoft.com>
+#
+# Copyright 2003 MandrakeSoft
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2, as
+# published by the Free Software Foundation.
+#
+# 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 standalone; #- warning, standalone must be loaded very first, for 'explanations'
+
+use common;
+use interactive;
+use network;
+use log;
+use c;
+use network::netconnect;
+
+$::isInstall and die "Not supported during install.\n";
+
+$::Wizard_pix_up = "wiz_drakgw.png"; #- to change ? keep existing one, nobody will see (too late) ;-)
+$::direct = grep { /-direct/ } @ARGV;
+
+
+#
+#my $sysconf_network = "/etc/sysconfig/network";
+#my $sysconf_dhcpd = "/etc/sysconfig/dhcpd";
+#my $rc_firewall_generic = "/etc/rc.d/rc.firewall";
+#my $rc_firewall_drakgw = "/etc/rc.d/rc.firewall.inet_sharing";
+#my $rc_firewall_24 = "/etc/rc.d/rc.firewall.inet_sharing-2.4";
+#my $masq_file = "/etc/shorewall/masq";
+#my $cups_conf = "/etc/cups/cupsd.conf";
+#
+#my $shorewall = network::shorewall::read();
+#
+#- get network configuration.
+my $netc = {};
+my $intf = {};
+network::read_all_conf('', $netc, $intf);
+
+my $in = 'interactive'->vnew('su');
+$::Wizard_title = N("PXE Server Configuration");
+
+!$::isEmbedded && $in->isa('interactive::gtk') and $::isWizard = 1;
+
+#pur_gtk_mode() if $::isEmbedded && $in->isa('interactive::gtk');
+
+sub sys { system(@_) == 0 or log::l("[drakpxe] Warning, sys failed for $_[0]") }
+
+sub outpend {
+ log::explanations("modified file $_[0]");
+ my $f = shift; local *F; open F, ">>$f" or die "outpend in file $f failed: $!\n"; print F foreach @_;
+}
+
+sub start_daemons () {
+ log::explanations("Starting daemons");
+
+ system("/etc/rc.d/init.d/dhcpd status >/dev/null") == 0 and sys("/etc/rc.d/init.d/dhcpd stop");
+
+ sys("/etc/rc.d/init.d/$_ start >/dev/null"), sys("/sbin/chkconfig --level 345 $_ on") foreach 'httpd', 'dhcpd';
+}
+
+sub stop_daemons () {
+ log::explanations("Stopping daemons");
+ foreach (qw(dhcpd httpd)) {
+ system("/etc/rc.d/init.d/$_ status >/dev/null 2>/dev/null") == 0 and sys("/etc/rc.d/init.d/$_ stop");
+ }
+ sys("/sbin/chkconfig --level 345 $_ off") foreach 'dhcpd', 'httpd';
+}
+
+my $wait_configuring;
+
+sub quit_global {
+ my ($in, $exitcode) = @_;
+ $in->exit($exitcode);
+ goto begin
+}
+
+sub fatal_quit ($) {
+ log::l("[drakpxe] FATAL: $_[0]");
+ undef $wait_configuring;
+ $in->ask_warn('', $_[0]);
+ quit_global($in, -1);
+}
+
+#my ($kernel_version) = c::kernel_version() =~ /(...)/;
+#log::l("[drakgw] kernel_version $kernel_version");
+#
+#$kernel_version >= 2.4 or fatal_quit(N("Sorry, we support only 2.4 kernels."));
+
+begin:
+
+#- **********************************
+#- * 0th step: verify if we have multiple network interface.
+
+$::Wizard_no_previous = 1;
+
+$::direct or $in->ask_okcancel(N("Installation Server Configuration"),
+N("You are about to configure your computer to install a PXE server as a DHCP server
+and a TFTP server to build an installation server.
+With that feature, other computers on your local network will be installable using this computer as source.
+
+Make sure you have configured your Network/Internet access using drakconnect before going any further.
+
+Note: you need a dedicated Network Adapter to set up a Local Area Network (LAN)."), 1) or quit_global($in, 0);
+
+undef $::Wizard_no_previous;
+
+
+#- **********************************
+#- * 1st step: verify if we have multiple network interface.
+
+step_check_intf:
+
+my @intf = grep { exists $_->{NETWORK} } map {
+ unless ($_->{NETWORK}) {
+ foreach my $s (split "\n", `route`) {
+ print STDERR "$s\n";
+ $s =~ /^(\S+)\s+\S+\s+$_->{NETMASK}\s+.*$_->{DEVICE}/ and $_->{NETWORK} = $1;
+ }
+ } $_ } values %$intf;
+if (@intf < 1) {
+ #- no interface already configured found, ask user to configure.
+ $in->ask_warn(N("No network adapter on your system!"),
+ N("No ethernet network adapter has been detected on your system. Please run the hardware configuration tool."));
+ quit_global($in, 0);
+} elsif (@intf > 1) {
+ #- there are more than one interface, we need to choose one of them.
+ @intf = $in->ask_from_listf(N("Choose the network interface"),
+ N("Please choose which network interface will be used for the dhcp server."),
+ sub { N("Interface %s (on network %s)", $_[0]{DEVICE}, $_[0]{NETWORK}) },
+ \@intf,
+ ) or goto begin;
+}
+
+
+#- **********************************
+#- * 3rd step: select installation directory to be used (if not present, next step
+#- will be creation and copy from existing one).
+
+step_ip_range:
+
+#- read current configuration, or create a default suitable automatically.
+my $dhcpd_conf = parse_dhcpd_conf("/etc/dhcpd.conf", {}, $netc, $intf[0]);
+
+#- get back default of ip.
+my $pool;
+foreach (@{$dhcpd_conf->{network}{pool}}) {
+ exists $_->{allow}{$dhcpd_conf->{class_PXE}} and $pool = $_, last;
+}
+my ($start_ip, $end_ip) = @{$pool || { start_ip => join('.', (split '\.', $intf[0]{NETWORK})[0..2], 16),
+ end_ip => join('.', (split '\.', $intf[0]{NETWORK})[0..2], 253) }}{qw(start_ip end_ip)};
+
+#- it become too complicated to handle address range, so ask user directly.
+$in->ask_from('DHCP Server Configuration',
+ N("The DHCP server will allow other computer to boot using PXE in the given range of address.
+
+The network address is %s using a netmask of %s.
+
+", @{$intf[0]}{qw(NETWORK NETMASK)}), [ { label => N("The DHCP start ip"), val => \$start_ip, type => 'entry' },
+ { label => N("The DHCP end ip"), val => \$end_ip, type => 'entry' }, ])
+ or goto begin;
+
+
+#- **********************************
+#- * 3rd step: select installation directory to be used (if not present, next step
+#- will be creation and copy from existing one).
+
+step_install_dir:
+
+my $dir = "/export"; #- TODO change according configuration?
+
+$in->ask_from('Choose the installation image directory',
+ N("Please indicate where the installation image will be available.
+
+If you do not have an existing directory, please copy the CD or DVD contents.
+
+"),
+ [ { label => N("Installation image directory"), val => \$dir, type => 'entry' }, ])
+ or goto step_ip_range;
+
+unless (-d $dir && -e "$dir/VERSION" && -d "$dir/isolinux" && -d "$dir/Mandrake/base") {
+ $in->ask_warn(N("No image found"),
+ N("No CD or DVD image found, please copy the installation program and rpm files."));
+ goto step_install_dir;
+}
+
+#- **********************************
+#- * 4st step: ask user for auto installation file.
+
+step_auto_install:
+
+my $auto_inst_cfg = "Mandrake/base/auto_inst.cfg"; #- TODO change according configuration?
+-e "$dir/$auto_inst_cfg" or $auto_inst_cfg = '';
+
+$in->ask_from('Choose auto installation',
+ N("Please indicate where the auto_install.cfg file is located.
+
+Leave it blank if you do not want to set up automatic installation mode.
+
+"),
+ [ { label => N("Location of auto_install.cfg file"), val => \$auto_inst_cfg, type => 'entry' }, ])
+ or goto step_install_dir;
+
+#- now install packages...
+my %rpm2file = ('dhcp-server' => '/usr/sbin/dhcpd',
+ 'pxe' => '/usr/sbin/pxe',
+ 'tftp-server' => '/usr/sbin/in.tftpd',
+ if_(! -x '/usr/sbin/httpd' && ! -x '/usr/sbin/httpd-perl', 'apache2' => '/usr/sbin/httpd2'));
+
+#- first: try to install all in one step
+my @needed_to_install = grep { !-e $rpm2file{$_} } keys %rpm2file;
+@needed_to_install and $in->do_pkgs->install(@needed_to_install);
+#- second: try one by one if failure detected
+if (any { !-e $rpm2file{$_} } keys %rpm2file) {
+ foreach (keys %rpm2file) {
+ -e $rpm2file{$_} or $in->do_pkgs->install($_);
+ -e $rpm2file{$_} or fatal_quit(N("Problems installing package %s", $_));
+ }
+}
+
+#- check if a pool already exist allowing PXE, else create one wich will be correct.
+if ($pool) {
+ @$pool{qw(start_ip end_ip)} = ($start_ip, $end_ip);
+} else {
+ $pool = { start_ip => $start_ip, end_ip => $end_ip };
+ foreach (keys %{$dhcpd_conf->{class}}) {
+ $pool->{$_ eq $dhcpd_conf->{class_PXE} || $_ eq 'Etherboot' ? 'allow' : 'deny'}{$_} = undef;
+ }
+ push @{$dhcpd_conf->{network}{pool}}, $pool;
+}
+build_dhcpd_conf($dhcpd_conf, "/etc/dhcpd.conf");
+
+#- make kernel and initrd available for initrd.
+mkdir "/var/lib/tftpboot/PXEClient/images";
+sys("cp", "-af", "$dir/isolinux/alt0", "/var/lib/tftpboot/PXEClient/images/");
+
+my $pxelinux_cfg = parse_pxelinux_cfg("/var/lib/tftpboot/PXEClient/pxelinux.cfg/default");
+my $label;
+foreach my $i (0..99) {
+ $label = undef;
+ foreach my $e (@{$pxelinux_cfg->{entry}}) {
+ $e->{label} eq "halt$i" and $label = "halt$i", last;
+ }
+ defined $label or $label = "halt$i", last;
+}
+my $server = $intf[0]{IPADDR} || $netc->{HOSTNAME};
+push @{$pxelinux_cfg->{entry}}, { label => $label,
+ kernel => "images/alt0/vmlinuz",
+ append => "initrd=images/alt0/all.rdz ramdisk=32000 vga=788 ".($auto_inst_cfg ? "kickstart=$auto_inst_cfg " : "")."automatic=method:http,network:dhcp,interface:eth0,dns:$netc->{dnsServer},server:$server,directory:$dir root=/dev/ram3" };
+build_pxelinux_cfg($pxelinux_cfg, "/var/lib/tftpboot/PXEClient/pxelinux.cfg/default");
+
+#- make directory available for httpd.
+log::explanations("Linking $dir in /var/www/html to make it available");
+system "mkdir", "-p", "/var/www/html/$dir";
+rmdir "/var/www/html/$dir";
+symlink $dir, "/var/www/html/$dir";
+
+stop_daemons();
+start_daemons();
+
+#- sub for reading/writing dhcpd.conf and pxelinux.cfg/default...
+sub parse_dhcpd_conf {
+ my ($file, undef, $netc, $intf) = @_;
+ my (%dhcpd_conf, $pool);
+ local (*F, $_);
+
+ #- fake reading configuration from dhcpd.conf file which is really too complex for this tools.
+ $dhcpd_conf{class_PXE} = 'PXE';
+ $dhcpd_conf{class} = { PXE => undef, Etherboot => undef, known => undef };
+ add2hash($dhcpd_conf{network} = { pool => [] }, $intf);
+ add2hash($dhcpd_conf{network}, $netc);
+
+ if (open F, $file) {
+ while (<F>) {
+ if (/^\s*pool\s*{/ .. /}/) {
+ /^\s*range\s+(\S+)\s+(\S+)\s*;/ and ($pool->{start_ip}, $pool->{end_ip}) = ($1, $2);
+ /^\s*(allow|deny)\s+members\s+of\s+"([^"]*)"\s*;/ and $pool->{$1}{$2} = undef;
+ /}/ and do { push @{$dhcpd_conf{network}{pool}}, $pool; $pool = undef };
+ }
+ }
+ close F;
+ }
+
+ \%dhcpd_conf;
+}
+
+sub build_dhcpd_conf {
+ my ($dhcpd_conf, $file) = @_;
+ local *F;
+ my $server = $dhcpd_conf->{network}{IPADDR} || $dhcpd_conf->{network}{HOSTNAME};
+ open F, ">$file" or return;
+ log::explanations("Modified file $file");
+ print F qq(# for explanation in french go to : http://www.delafond.org/traducmanfr/man/man5/dhcpd.conf.5.html
+ddns-update-style none;
+allow booting;
+allow bootp;
+
+# Your dhcp server is not master on your network !
+#not authoritative;
+# Your dhcpd server is master on your network !
+#authoritative;
+not authoritative;
+
+#Interface where dhcpd is active
+DHCPD_INTERFACE = "$dhcpd_conf->{network}{DEVICE}";
+
+# Definition of PXE-specific options
+# Code 1: Multicast IP address of bootfile
+# Code 2: UDP port that client should monitor for MTFTP responses
+# Code 3: UDP port that MTFTP servers are using to listen for MTFTP requests
+# Code 4: Number of secondes a client must listen for activity before trying
+# to start a new MTFTP transfer
+# Code 5: Number of secondes a client must listen before trying to restart
+# a MTFTP transfer
+
+# define Option for the PXE class
+option space PXE;
+option PXE.mtftp-ip code 1 = ip-address;
+option PXE.mtftp-cport code 2 = unsigned integer 16;
+option PXE.mtftp-sport code 3 = unsigned integer 16;
+option PXE.mtftp-tmout code 4 = unsigned integer 8;
+option PXE.mtftp-delay code 5 = unsigned integer 8;
+option PXE.discovery-control code 6 = unsigned integer 8;
+option PXE.discovery-mcast-addr code 7 = ip-address;
+
+#Define options for pxelinux
+option space pxelinux;
+option pxelinux.magic code 208 = string;
+option pxelinux.configfile code 209 = text;
+option pxelinux.pathprefix code 210 = text;
+option pxelinux.reboottime code 211 = unsigned integer 32;
+site-option-space "pxelinux";
+# These lines should be customized to your setup
+#option pxelinux.configfile "configs/common";
+#option pxelinux.pathprefix "/pxelinux/files/";
+#filename "/pxelinux/pxelinux.bin";
+
+option pxelinux.magic f1:00:74:7e;
+option pxelinux.reboottime 30;
+#if exists dhcp-parameter-request-list {
+ # Always send the PXELINUX options
+# append dhcp-parameter-request-list 208, 209, 210, 211;
+# append dhcp-parameter-request-list 208,211;
+# }
+
+#Class that determine the options for Etherboot 5.x requests
+class "Etherboot" {
+
+#if The vendor-class-identifier equal Etherboot-5.0
+match if substring (option vendor-class-identifier, 0, 9) = "Etherboot";
+
+# filename define the file retrieve by the client, there nbgrub
+# our tftp is chrooted so is just the path to the file
+filename "/etherboot/nbgrub";
+
+#Used by etherboot to detect a valid pxe dhcp server
+option vendor-encapsulated-options 3c:09:45:74:68:65:72:62:6f:6f:74:ff;
+
+# Set the "vendor-class-identifier" field to "PXEClient" in dhcp answer
+# if this field is not set the pxe client will ignore the answer !
+option vendor-class-identifier "Etherboot";
+
+vendor-option-space PXE;
+option PXE.mtftp-ip 0.0.0.0;
+
+# IP of you TFTP server
+next-server $server;
+}
+
+
+# create the Class PXE
+class "PXE" {
+# if the "vendor-class-identifier" is set to "PXEClient" in the client dhcp request
+match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
+
+# filename define the file retrieve by the client, there pxelinux.0
+# our tftp is chrooted so is just the path to the file
+# If you prefer use grub, use pxegrub compiled for your ethernet card.
+#filename "/PXEClient/pxegrub";
+filename "/PXEClient/pxelinux.0";
+
+# Set the "vendor-class-identifier" field to "PXEClient" in dhcp answer
+# if this field is not set the pxe client will ignore the answer !
+option vendor-class-identifier "PXEClient";
+
+
+vendor-option-space PXE;
+option PXE.mtftp-ip 0.0.0.0;
+
+# IP of you TFTP server
+next-server $server;
+}
+
+# the class know exist just for deny the response to other DHCP request
+class "known" {
+ match hardware;
+ one-lease-per-client on;
+ ddns-updates on;
+ ddns-domainname = "$dhcpd_conf->{network}{DOMAINNAME}";
+ option domain-name "$dhcpd_conf->{network}{DOMAINNAME}";
+ option domain-name-servers $dhcpd_conf->{network}{dnsServer};
+ ddns-hostname = pick-first-value(ddns-hostname, option host-name);
+ option fqdn.no-client-update on;
+ set vendor_class_identifier = option vendor-class-identifier;
+}
+
+# Tags uses by setup_node_mac_to_dhcp
+# TAG: NODE_LIST_BEGIN
+
+# TAG: NODE_LIST_END
+shared-network "mynetwork" {
+ subnet $dhcpd_conf->{network}{NETWORK} netmask $dhcpd_conf->{network}{NETMASK} {
+ option subnet-mask $dhcpd_conf->{network}{NETMASK};
+ option routers $dhcpd_conf->{network}{GATEWAY};
+ default-lease-time 28800;
+ max-lease-time 86400;
+ option domain-name "$dhcpd_conf->{network}{DOMAINNAME}";
+ option domain-name-servers $dhcpd_conf->{network}{dnsServer};
+# Used by clusterautosetup-client to find its server
+ next-server $server;
+
+);
+ foreach (@{$dhcpd_conf->{network}{pool}}) {
+ print F " pool {
+ range $_->{start_ip} $_->{end_ip};
+";
+ print F " allow members of \"$_\";\n" foreach keys %{$_->{allow}};
+ print F " deny members of \"$_\";\n" foreach keys %{$_->{deny}};
+ print F " }\n";
+ }
+print F qq(
+
+# pool {
+# range 192.168.200.200 192.168.200.254;
+# give an address of the the pool for PXE client and deny the other
+#allow members of "PXE";
+#deny members of "known";
+#allow members of "Etherboot";
+# }
+ }
+}
+);
+ close F;
+}
+
+sub parse_pxelinux_cfg {
+ my ($file) = @_;
+ my (%pxelinux_cfg, $entry);
+ local (*F, $_);
+
+ if (open F, $file) {
+ while (<F>) {
+ chomp;
+ s/#.*//; next if /^\s*$/;
+ if (/^\s*(PROMPT|DEFAULT|DISPLAY|TIMEOUT)\s+(.*)/i) {
+ $pxelinux_cfg{$1} = $2;
+ } elsif (/^\s*label\s+(.*)/i) {
+ $entry and push @{$pxelinux_cfg{entry}}, $entry;
+ $entry = { label => $1 },
+ } elsif (/^\s*(LOCALBOOT|KERNEL|APPEND)\s+(.*)/i) {
+ $entry->{$1} = $2;
+ } else {
+ log::l("ignoring line in file $file due to parsing error");
+ }
+ }
+ $entry and push @{$pxelinux_cfg{entry}}, $entry;
+ close F;
+ }
+ #- try to fix bad file (first version of drakpxe for example).
+ my %default_pxelinux_cfg = (PROMPT => 1,
+ DEFAULT => "local",
+ DISPLAY => "messages",
+ TIMEOUT => 50,
+ entry => [ { label => "local",
+ LOCALBOOT => 0 } ],
+ );
+ foreach (qw(PROMPT DEFAULT DISPLAY TIMEOUT entry)) {
+ length $pxelinux_cfg{$_} > 0 or $pxelinux_cfg{$_} = $default_pxelinux_cfg{$_};
+ }
+ \%pxelinux_cfg;
+}
+
+sub build_pxelinux_cfg {
+ my ($pxelinux_cfg, $file) = @_;
+ local *F;
+ open F, ">$file" or return;
+ log::explanations("Modified file $file");
+ foreach (keys %$pxelinux_cfg) {
+ /^entry$/ and next;
+ print F "$_ $pxelinux_cfg->{$_}\n";
+ }
+ foreach my $e (@{$pxelinux_cfg->{entry}}) {
+ print F "label $e->{label}\n";
+ foreach (keys %$e) {
+ /^label$/ and next;
+ print F " $_ $e->{$_}\n";
+ }
+ }
+ close F;
+}
+