source: trunk/debathena/config/recovery-mode-config/debian/athena-renumber @ 24398

Revision 24398, 5.3 KB checked in by jdreed, 14 years ago (diff)
In recovery-mode-config: * Catch SIGINT in athena-renumber so that sulogin doesn't get upset
  • Property svn:executable set to *
Line 
1#!/usr/bin/perl -w
2#
3# A script to change the IP/hostname on a cluster machine
4# jdreed@mit.edu
5
6use strict;
7use Socket;
8use File::Copy;
9use Getopt::Std;
10
11# sulogin gets upset if it gets a ^C
12$SIG{'INT'} = 'bail';
13
14my $MASKS="/usr/share/debathena-recovery-mode-config/masks";
15
16if (defined($ARGV[0]) && ($ARGV[0] eq 'test')) {
17    print "Change IP address or hostname\n";
18    exit 0;
19}
20
21sub confirm {
22    my $question = shift || "Continue?";
23    print "${question} (y/n) ";
24    my $ans = <STDIN>;
25    return ($ans =~ m/^y$/i);
26}
27
28sub bail {
29    if ($_[0] eq 'INT') {
30        print "\nCancelled.";
31    } else {
32        print shift;
33    }
34    print "\n\n(press ENTER to return to the recovery mode menu)\n";
35    my $dummy = <STDIN>;
36    exit 0;
37}
38
39sub mask {
40    my $ip = shift;
41    my $mask = shift;
42    my $mbits = pack("B*", (1 x $mask) . (0 x (32 - $mask)));
43    my $ibits = pack("CCCC", split(/\./, $ip));
44    my $net = $ibits & $mbits;
45    return join('.', unpack("CCCC", $net));
46}
47
48sub cidr2ip {
49    my $cidr = shift;
50    return join('.', unpack("CCCC", pack("B*", (1 x $cidr) . (0 x (32 - $cidr)))));
51}
52
53sub validIP {
54    my $ip = shift;
55    if ($ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) {
56        if (scalar(grep { ($_ <= 255) && ($_ >= 0) } ($1, $2, $3, $4)) == 4) {
57            return 1;
58        }
59    }
60    return 0;
61}
62
63# main
64
65# Sanity checks
66foreach (qw(/etc/network/interfaces /etc/hosts /etc/hostname)) {
67    (-w $_) || bail("Cannot write to $_. (Are you root?)");
68}
69
70(-r $MASKS) || bail("Cannot read $MASKS");
71
72my $machtype = `machtype -L`;
73chomp($machtype);
74if ($machtype ne 'debathena-cluster') {
75    print "WARNING: This script is designed for debathena-cluster machines but\n";
76    print "this machine is running $machtype.\n";
77    confirm("Are you SURE you want to continue?") || bail("OK, cancelled.");
78}
79
80my $ip = '';
81until (validIP($ip)) {
82    if ($ip) {
83        print "Invalid IP address ($ip).  Try again.\n";
84    }
85    print "Enter the new IP address: ";
86    ($ip = <STDIN>) =~ s/\s//g;
87}
88print "Looking up hostname...";
89my $fqdn = gethostbyaddr(inet_aton($ip), AF_INET);
90if ($fqdn) {
91    print " found.\n";
92} else {
93    $fqdn = '';
94    print " not found.\n";
95    until ($fqdn =~ /^[a-z][\w\-\.]*/i) {
96        print "Please enter the machine's new hostname: ";
97        ($fqdn = <STDIN>) =~ s/\s//g;
98    }
99}
100$fqdn = lc($fqdn);
101my $hostname = $fqdn;
102if ($fqdn =~ /\./) {
103    $hostname = (split(/\./, $fqdn))[0];
104} else {
105    print "NOTE: No domain specified, assuming 'mit.edu'";
106    $fqdn = "${hostname}.mit.edu";
107}
108
109my ($subnetmask, $gateway);
110print "Looking up netmask information...\n";
111open(MASKS, $MASKS) || bail("Cannot read $MASKS: $!");
112while (<MASKS>) {
113    next if (/^#/);
114    next unless (/\d/);
115    my ($addr, $sbits, $mbits, $gw) = split(' '); #the ' ' pattern emulates awk
116    if (mask($ip, $sbits) eq $addr) {
117        $subnetmask = cidr2ip($mbits);
118        if (! $gw) {
119            my @octets = split(/\./, mask($ip, $mbits));
120            my $trailing = pop(@octets) + 1;
121            $gateway = join('.', @octets, $trailing);
122        } else {
123            $gateway = $gw;
124        }
125        last;
126    }
127}
128(defined($subnetmask) && defined($gateway)) || bail("Could not find a matching line in masks file for $ip.\nIf you are sure you typed the IP address correctly, please report\nthis error to IS&T, along with the IP address you were trying to use.");
129
130close(MASKS);
131print "IP address:  $ip\n";
132print "Subnet Mask: $subnetmask\n";
133print "Gateway:     $gateway\n";
134print "Hostname:    $hostname\n";
135print "FQDN:        $fqdn\n\n";
136
137confirm("Does that look correct?") || bail("OK, cancelled.");
138
139print "Updating /etc/network/interfaces...\n";
140copy("/etc/network/interfaces", "/etc/network/interfaces.old") || bail("Could not copy /etc/network/interfaces");
141open(INTERFACES, ">/etc/network/interfaces") || bail ("Could not overwrite /etc/network/interfaces: $!");
142print INTERFACES <<"ENDINTERFACES";
143# This file was created by $0
144
145# The loopback interface
146auto lo
147iface lo inet loopback
148
149# The primary network interface
150auto eth0
151iface eth0 inet static
152        address $ip
153        netmask $subnetmask
154        gateway $gateway
155        dns-nameservers 18.70.0.160 18.71.0.151 18.72.0.3
156ENDINTERFACES
157close(INTERFACES);
158
159print "Updating /etc/hosts...\n";
160
161copy("/etc/hosts", "/etc/hosts.old") || bail("Could not copy /etc/hosts");
162open(HOSTS, ">/etc/hosts") || bail ("Could not overwrite /etc/hosts: $!");
163print HOSTS <<"ENDHOSTS";
164# This file was created by $0
165127.0.0.1       localhost
166127.0.1.1       $fqdn $hostname
167
168# The following lines are desirable for IPv6 capable hosts
169::1     localhost ip6-localhost ip6-loopback
170fe00::0 ip6-localnet
171ff00::0 ip6-mcastprefix
172ff02::1 ip6-allnodes
173ff02::2 ip6-allrouters
174ff02::3 ip6-allhosts
175ENDHOSTS
176close(HOSTS);
177                                   
178print "Updating /etc/hostname...\n";
179copy("/etc/hostname", "/etc/hostname.old") || bail("Could not copy /etc/hostname");
180open(HOSTNAME, ">/etc/hostname") || bail ("Could not overwrite /etc/hostname: $!");
181print HOSTNAME "$hostname\n";
182close(HOSTNAME);
183
184print "Setting hostname...\n";
185system("/bin/hostname", $hostname);
186print "\nDone!  You will need to reboot the workstation for the\n";
187print "changes to take effect.\n";
188confirm("Would you like to reboot now?") || bail("Please perform a full shutdown and reboot as soon as possible.");
189print "The workstation will now power down completely.\n";
190print "When you turn it back on, it will use the new IP address.\n\n";
191print "(press ENTER to power down the workstation)";
192getc(STDIN);
193system("/sbin/poweroff");
194exit 0;
Note: See TracBrowser for help on using the repository browser.