[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 2 of 3] Emergency Network Reset script


  • To: xen-api@xxxxxxxxxxxxxxxxxxx
  • From: Rob Hoes <rob.hoes@xxxxxxxxxx>
  • Date: Tue, 10 Aug 2010 17:10:30 +0100
  • Delivery-date: Tue, 10 Aug 2010 09:12:00 -0700
  • List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>

# HG changeset patch
# User Rob Hoes <rob.hoes@xxxxxxxxxx>
# Date 1281455715 -3600
# Node ID d15252d6d4137f7aaeffe61f537c336a5a4277e3
# Parent  df2566c65c388924a9e096228ba5478e08c8fffe
Emergency Network Reset script

This patch creates the script xe-reset-networking, which is able to trigged a 
network reset on the host it is executed on.

See the design page at 
http://wiki.xensource.com/xenwiki/Emergency_Network_Reset for more information 
and usage details.

Signed-off-by: Rob Hoes <rob.hoes@xxxxxxxxxx>

diff -r df2566c65c38 -r d15252d6d413 scripts/OMakefile
--- a/scripts/OMakefile
+++ b/scripts/OMakefile
@@ -49,6 +49,7 @@
        $(IPROG) debug_ha_query_liveset $(DESTDIR)/opt/xensource/debug
        $(IPROG) xe-scsi-dev-map $(DESTDIR)/opt/xensource/bin/
        $(IPROG) xe-mount-iso-sr $(DESTDIR)/opt/xensource/bin/
+       $(IPROG) xe-reset-networking $(DIST)/staging/opt/xensource/bin/
        $(IPROG) xe-set-iscsi-iqn $(DESTDIR)/opt/xensource/bin/
        $(IPROG) xe-toolstack-restart $(DESTDIR)/opt/xensource/bin/
        $(IPROG) xe-xentrace $(DESTDIR)/opt/xensource/bin/
diff -r df2566c65c38 -r d15252d6d413 scripts/xe-reset-networking
--- /dev/null
+++ b/scripts/xe-reset-networking
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+
+"""
+Copyright (C) 2006-2009 Citrix Systems Inc.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; version 2.1 only. with the special
+exception on linking described in file LICENSE.
+
+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 Lesser General Public License for more details.
+"""
+
+import sys
+import os
+import commands
+import time
+from optparse import OptionParser
+#import XenAPI
+
+pool_conf = '/etc/xensource/pool.conf'
+interface_reconfigure = '/opt/xensource/libexec/interface-reconfigure'
+inventory_file = '/etc/xensource-inventory'
+network_reset = '/tmp/network-reset'
+
+# read inventory file
+def read_inventory():
+       f = open(inventory_file, 'r')
+       inventory = {}
+       for l in f.readlines():
+               kv = l.split('=')
+               inventory[kv[0]] = kv[1][1:-2]
+       return inventory
+       
+def write_inventory(inventory):
+       f = open(inventory_file, 'w')
+       for k in inventory:
+               f.write(k + "='" + inventory[k] + "'\n")
+       f.close()
+       
+def biosdevname(d):
+       try:
+               p = os.popen('biosdevname -i ' + d)
+               return p.read().strip()
+       except:
+               return d
+
+if __name__ == "__main__":
+       parser = OptionParser()
+       parser.add_option("-m", "--master", help="Master's address", 
dest="address", default=None)
+       parser.add_option("--mac", help="MAC address of new management 
interface", dest="mac", default=None)
+       parser.add_option("--mode", help='IP configuration mode for new 
management interface: "dhcp" or "static" (default is dhcp)', dest="mode", 
default="dhcp")
+       parser.add_option("--ip", help="IP address for new management 
interface", dest="ip", default='')
+       parser.add_option("--netmask", help="Netmask for new management 
interface", dest="netmask", default='')
+       parser.add_option("--gateway", help="Gateway for new management 
interface", dest="gateway", default='')
+       parser.add_option("--dns", help="DNS server for new management 
interface", dest="dns", default='')
+       (options, args) = parser.parse_args()
+       
+       # Determine pool role
+       try:
+               f = open(pool_conf, 'r')
+               try:
+                       l = f.readline()
+                       ls = l.split(':')
+                       if ls[0] == 'master':
+                               master = True
+                               address = 'localhost'
+                       else:
+                               master = False
+                               address = ls[1]
+               finally:
+                       f.close()
+       except:
+               pass
+       
+       # Check if a MAC is given
+       if options.mac == None:
+               parser.error("please specify the MAC address of the management 
interface")
+               sys.exit(1)
+       else:
+               mac = options.mac.lower()
+               
+       # Determine IP configuration for management interface
+       options.mode = options.mode.lower()
+       if options.mode not in ["dhcp", "static"]:
+               parser.error('mode should be either "dhcp" or "static"')
+               sys.exit(1)
+               
+       if options.mode == 'static' and (options.ip == '' or options.netmask == 
''):
+               parser.error("if static IP mode is selected, an IP address and 
netmask need to be specified")
+               sys.exit(1)
+       
+       # Warn user
+       res = raw_input("This command will reboot the host and reset its 
network configuration.\nAny running VMs should first be shut down.\nType 'yes' 
to continue.\n")
+       if res <> 'yes':
+               sys.exit(1)
+       
+       # Update master's IP, if needed and given
+       if master == True and options.address != None:
+               address = options.address
+               print "Setting master's ip (" + address + ")..."
+               try:
+                       f = open(pool_conf, 'w')
+                       f.write('slave:' + address)
+               finally:
+                       f.close()
+       
+       # Stop networking subsystem to ensure bonds etc are down
+       os.system('service network stop')
+       
+       # Find existing network interfaces (MAC and device name)
+       sysfs = '/sys/class/net/'
+       device = None
+       # iterate over all devices
+       for d in os.listdir(sysfs):
+               # only continue if it is a physical device
+               if os.access(sysfs + d + '/device', os.F_OK):
+                       # try to get the MAC
+                       m = None
+                       try:
+                               f = open(sysfs + d + '/address', 'r')
+                               m = f.readline()[:-1].lower()
+                       finally:
+                               f.close()
+                       if m == mac:
+                               device = biosdevname(d)
+                               break
+       
+       # Find current device name for management interface
+       if device == None:
+               print "Could not find MAC", mac
+               print "Aborting."
+               sys.exit(1)
+               
+       # Construct bridge name for management interface based on convention
+       if device[:3] == 'eth':
+               bridge = 'xenbr' + device[3:]
+       else:
+               bridge = 'br' + device
+       
+       # Ensure xapi is not running
+       print "Stopping xapi..."
+       os.system('service xapi stop >/dev/null 2>/dev/null')
+       
+       # Reconfigure new management interface
+       print "Reconfiguring " + device + "..."
+       if_args = ' --force ' + bridge + ' rewrite --mac=' + mac + ' --device=' 
+ device + ' --mode=' + options.mode
+       if options.mode == 'static':
+               if_args += ' --ip=' + options.ip + ' --netmask=' + 
options.netmask
+               if options.gateway != '':
+                       if_args += ' --gateway=' + options.gateway
+       os.system(interface_reconfigure + if_args + ' >/dev/null 2>/dev/null')
+
+       # Update interfaces in inventory file
+       print 'Updating inventory file...'
+       inventory = read_inventory()
+       inventory['MANAGEMENT_INTERFACE'] = bridge
+       inventory['CURRENT_INTERFACES'] = ''
+       write_inventory(inventory)
+       
+       # Write trigger file for XAPI to continue the network reset on startup
+       try:
+               f = file(network_reset, 'w')
+               f.write('MAC=' + mac + '\n')
+               f.write('MODE=' + options.mode + '\n')
+               if options.mode == 'static':
+                       f.write('IP=' + options.ip + '\n')
+                       f.write('NETMASK=' + options.netmask + '\n')
+                       if options.gateway != '':
+                               f.write('GATEWAY=' + gateway + '\n')
+                       if options.dns != '':
+                               f.write('DNS=' + dns + '\n')
+       finally:
+               f.close()
+       
+       # Reboot
+       os.system("/sbin/reboot")
+
 scripts/OMakefile           |    1 +
 scripts/xe-reset-networking |  180 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+), 0 deletions(-)


Attachment: xen-api.hg-2.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.