ansible/files/common-scripts/hardware-reinstall

228 lines
8 KiB
Python
Executable file

#!/usr/bin/env python
# hardware-reinstall - Prepare a physical box in FI for re-install.
# (c) 2012 Red Hat, Inc.
# Ricky Elrod <codeblock@fedoraproject.org>
# GPLv2+
import os
import sys
import urllib
import socket
import subprocess
import shlex
import platform
from optparse import OptionParser
parser = OptionParser(
description='Prepare a physical box in FI for re-install.')
parser.add_option('-n',
'--noop',
action='store_true',
help="Don't actually modify/download anything, just "
"output stuff.")
parser.add_option('-y',
'--yes',
action='store_true',
default=False,
dest="yes",
help="Don't prompt to confirm, just do it.")
parser.add_option('--ip',
help="Override the IP of the box (passed to Grubby)")
parser.add_option('--gw',
help="Override the Gateway of the box (passed to Grubby)",
dest='gateway')
parser.add_option('--nm',
help="Override the Netmask of the box (passed to Grubby)",
dest='netmask')
parser.add_option('--dns',
help="Comma-delimited list of DNS resolvers (passed to "
"Grubby)",
dest='dns_resolvers')
parser.add_option('--ks-file',
help="Set the kickstart file to use (default:"
"hardware-rhel-6-nohd)",
default='hardware-rhel-6-nohd',
dest='ks_file')
(options, args) = parser.parse_args()
if options.yes and options.noop:
print "Don't ask AND don't do anything? Cmon"
sys.exit(1)
# 0. Get our hostname/primary ip
# Get our primary IP by resolving our hostname.
if options.ip:
if not options.netmask:
print 'You gave a custom IP and should specify a custom netmask too.'
sys.exit(1)
primary_ip = options.ip
else:
primary_ip = socket.gethostbyname(socket.gethostname())
# so - anaconda sometimes doesn't seem to listen to our dns
# when fetching kickstarts, etc - so if we give the ip of the host
# if we're in 10.5.X network (phx2) then things just work.
if primary_ip.startswith('10.5.'):
basehost = "http://10.5.126.23/"
else:
basehost = "http://infrastructure.fedoraproject.org/"
arch = platform.machine()
VMLINUZ_URL = '%srepo/rhel/RHEL6-%s/images/pxeboot/vmlinuz' % (basehost, arch)
INITRD_URL = '%srepo/rhel/RHEL6-%s/images/pxeboot/initrd.img' % (basehost,
arch)
# 1. Grab initrd and vmlinuz and throw them in /boot
# FIXME - more error catching here
if not options.noop:
print 'Fetching vmlinuz'
urllib.urlretrieve(VMLINUZ_URL, "/boot/vmlinuz-install")
print 'Fetching initrd'
urllib.urlretrieve(INITRD_URL, "/boot/initrd-install.img")
# 2. Find our network info.
if options.netmask:
primary_netmask = options.netmask
# We still have to get the MAC address, of the primary NIC
# even if we specify a custom IP/NM.
cmd = subprocess.Popen('/sbin/ifconfig', stdout=subprocess.PIPE)
stdout = cmd.communicate()[0]
i = 0
lines = stdout.split("\n")
for line in lines:
if socket.gethostbyname(socket.gethostname()) in line:
# Somewhere between EL6 and F17, ifconfig output has changed.
# We accommodate for both.
if ':' in line:
# We are EL6
if not options.netmask:
# inet addr:10.5.127.51 Bcast:10.5.127.255 Mask:255.255.255.0
primary_netmask = line.split('Mask:')[1]
# On EL6 MAC addr is always one line before the IP address line
primary_mac = lines[i - 1].split('HWaddr ')[1]
else:
# We are likely something newer
if not options.netmask:
# inet 10.10.10.113 netmask 255.255.255.0 broadcast
# 10.10.10.255 # (cont. from above comment)
primary_netmask = line.split('netmask ')[1].split(' ')[0]
# On newer things, life gets harder. We have to continue
# parsing lines until we get one with 'ether ' in it.
# The range is the line we're on now -> the last line.
for y in xrange(i, len(lines) - 1):
if 'ether ' in lines[y]:
primary_mac = lines[y].split('ether ')[1].split(' ')[0]
break
break
i += 1
# Gateway
if options.gateway:
primary_gateway = options.gateway
else:
cmd = subprocess.Popen(['/sbin/ip', 'route'], stdout=subprocess.PIPE)
stdout = cmd.communicate()[0]
for line in stdout.split("\n"):
if 'default' in line:
# default via 10.10.10.1 dev wlan0 proto static
primary_gateway = line.split('via ')[1].split(' ')[0]
break
# And DNS servers
if options.dns_resolvers:
dns_resolvers = options.dns_resolvers
else:
dns_servers = []
with open('/etc/resolv.conf', 'r') as f:
for line in f.readlines():
if 'nameserver' in line:
dns = line.split(' ')
if len(dns) == 2:
dns_servers.append(dns[1].strip())
dns_resolvers = ','.join(dns_servers)
print '-' * 30
print 'Primary IP: ' + primary_ip
print 'Primary Netmask: ' + primary_netmask
print 'Primary Gateway: ' + primary_gateway
print 'Primary MAC Address: ' + primary_mac
print 'DNS Resolvers: ' + dns_resolvers
print '-' * 30
# 3. Construct the grubby line.
# grubby --add-kernel=/boot/vmlinuz-install \
# --args="ks=http://infrastructure.fedoraproject.org/\
# repo/rhel/ks/hardware-rhel-6-nohd \
# repo=http://infrastructure.fedoraproject.org/repo/rhel/RHEL6-x86_64/ \
# ksdevice=link ip=$IP gateway=$GATEWAY netmask=$NETMASK dns=$DNS" \
# --title="install el6" --initrd=/boot/initrd-install.img
grubby_command = '/sbin/grubby --add-kernel=/boot/vmlinuz-install ' \
'--args="ks=%srepo/rhel/ks/%s ksdevice=%s ' \
'ip=%s gateway=%s netmask=%s dns=%s repo=%srepo/rhel/RHEL6-x86_64/" ' \
'--title="install el6" --initrd=/boot/initrd-install.img' % (basehost,
options.ks_file,
primary_mac,
primary_ip,
primary_gateway,
primary_netmask,
dns_resolvers,
basehost)
print 'This grubby command seems like it will work:'
print '-' * 30
print grubby_command
print '-' * 30
print 'Check the command and be sure that it looks correct.'
if not options.noop:
if not options.yes:
print 'Type yes to continue, anything else to abort.'
print 'By continuing, I will run the above command.'
if raw_input('> ') != 'yes':
print 'Removing downloaded files.'
os.unlink('/boot/vmlinuz-install')
os.unlink('/boot/initrd-install.img')
print 'Aborting.'
sys.exit(1)
cmd = subprocess.Popen(shlex.split(grubby_command),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = cmd.communicate()
if stdout:
print stdout
if stderr:
print "[STDERR output]"
print stderr
if not options.yes:
raw_input(
'Examine the above output, if it looks sane, press enter to '
'continue.')
print 'The next command I will run is:'
print 'echo "savedefault --default=0 --once" | grub --batch'
if not options.noop:
cmd = subprocess.Popen(['/sbin/grub', '--batch'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout = cmd.communicate(input='savedefault --default=0 --once\n')
print stdout[0]
print 'Done.'
print 'When you are ready, run: `shutdown -r now` to reboot.'
print 'Go here:'
print 'http://infrastructure.fedoraproject.org/infra/docs/kickstarts.txt'
print 'And control-f for "Installation" (no quotes). Continue from there.'
if options.noop:
print '-' * 30
print 'Script was run in "no-op" mode - none of the above commands ' \
'actually ran.'
print '-' * 30