def extract(host, tar_file, cd_dir): from Exscript import Account from Exscript.util.start import start from Exscript.util.match import first_match from Exscript.protocols.Exception import InvalidCommandException def starting_host(protocol, index, data): print data.group(index) def lab_started(protocol, index, data): print "Lab started" def do_something(thread, host, conn): conn.add_monitor(r'Starting (\S+)', starting_host) conn.add_monitor(r'The lab has been started', lab_started) #conn.data_received_event.connect(data_received) conn.execute('tar -xzf %s' % tar_file) conn.execute('cd %s' % cd_dir) conn.execute('vlist') conn.execute("lclean") print "Starting lab" start_command = 'lstart -p5 -o --con0=none' try: conn.execute(start_command) except InvalidCommandException, error: if "already running" in str(error): print "Already Running" #TODO: handle appropriately print "Halting previous lab" conn.execute("vclean -K") print "Halted previous lab" print "Starting lab" conn.execute(start_command) first_match(conn, r'^The lab has been started') print "HERE" conn.send("exit")
def extract(host, tar_file, cd_dir): from Exscript import Account from Exscript.util.start import start from Exscript.util.match import first_match from Exscript.protocols.Exception import InvalidCommandException def starting_host(protocol, index, data): print data.group(index) def lab_started(protocol, index, data): print "Lab started" def do_something(thread, host, conn): conn.add_monitor(r"Starting (\S+)", starting_host) conn.add_monitor(r"The lab has been started", lab_started) # conn.data_received_event.connect(data_received) conn.execute("tar -xzf %s" % tar_file) conn.execute("cd %s" % cd_dir) conn.execute("vlist") conn.execute("lclean") print "Starting lab" start_command = "lstart -p5 -o --con0=none" try: conn.execute(start_command) except InvalidCommandException, error: if "already running" in str(error): print "Already Running" # TODO: handle appropriately print "Halting previous lab" conn.execute("vclean -K") print "Halted previous lab" print "Starting lab" conn.execute(start_command) first_match(conn, r"^The lab has been started") print "HERE" conn.send("exit")
def config(self,resp): ret = "" if not isinstance(resp, str): print "No Config found" return "" remove = [ "^\!", #Remove comments "^Time: ", #Remove timestamp from nxos "^show running-config", "^Building configuration", "Current configuration \: \d+ bytes", ] #Find hostname and put it on top. for line in resp.splitlines(): #Remove lines matcing "remove" variable r = False for _remove in remove: if re.search(_remove,line): r = True if r: continue #Remove Timestamp from NX-OS # if re.search("^Time: ",line): continue #Removing passwords from configuration a = first_match(line, "^((enable )?(password|passwd)( level \d+)?)", re.I) if a[0] and self._config["filter_pw"] >= 1: ret += "!%s <removed>\n" % a[0] continue a = first_match(line, "^(username (\S+)(\s.*)? secret)", re.I) if a[0] and self._config["filter_pw"] >= 1: ret += "!%s <removed>\n" % a[0] continue a = first_match(line, "^(enable secret) ", re.I) if a and self._config["filter_pw"] >= 1: ret += "!%s <removed>\n" % a continue a = first_match(line, "^(username (\S+)(\s.*)? (privilege \d+ )?(password|secret) )((\d) \S+|\S+)", re.I) if a[0] and self._config["filter_pw"] >= 1: ret += "!%s <removed>\n" % a[0] continue a = first_match(line, "^hostname", re.I) if a: ret += "%s\n" % a continue ret += "%s\n" % line return ret
def extract(host, username, tar_file, cd_dir, timeout = 3600, key_filename = None, password = None, verbosity = 0): """Extract and start lab""" log.debug("Extracting and starting lab on %s" % (host)) log.info("Extracting and starting Netkit lab") from Exscript import Account from Exscript.util.start import start from Exscript.util.match import first_match from Exscript import PrivateKey from Exscript.protocols.Exception import InvalidCommandException, LoginFailure messaging = ank_messaging.AnkMessaging() def starting_host(protocol, index, data): m = re.search('\\"(\S+)\\"', data.group(index)) if m: hostname = m.group(1) log.info(data.group(index)) #TODO: use regex to strip out just the machine name body = {"starting": hostname} messaging.publish_json(body) def lab_started(protocol, index, data): log.info("Lab started on %s" % host) body = {"lab started": host} messaging.publish_json(body) def make_not_found(protocol, index, data): log.warning("Make not installed on remote host %s. Please install make and retry." % host) return def start_lab(thread, host, conn): conn.set_timeout(timeout) conn.add_monitor(r'Starting (\S+)', starting_host) conn.add_monitor(r'The lab has been started', lab_started) conn.add_monitor(r'make: not found', make_not_found) #conn.data_received_event.connect(data_received) conn.execute('cd %s' % cd_dir) conn.execute('lhalt -q') conn.execute('lcrash -k') conn.execute("lclean") conn.execute('cd') # back to home directory tar file copied to conn.execute('rm -Rf rendered') conn.execute('tar -xzf %s' % tar_file) conn.execute('cd %s' % cd_dir) conn.execute('vlist') conn.execute("lclean") log.info("Starting lab") start_command = 'lstart -p20 -o--con0=none' try: conn.execute(start_command) except InvalidCommandException, error: if "already running" in str(error): time.sleep(1) conn.execute(start_command) first_match(conn, r'^The lab has been started') conn.send("exit")
def port_FREE(switch, username, password, verbose, snakerange): error = [] snakearray = port_extractor(snakerange) conn = login(switch, username, password, verbose) #first check if we may disable all the ports in the snake-array, is there a 'SNAKEPORT' in its port-name? for port in snakearray: conn.execute('show interfaces ' + port + ' | include Port name') maydisable = first_match(conn, r'(SNAKETEST:)') if maydisable != 'SNAKETEST:': error.append( 'interface ' + port + ' has no port-name with "SNAKETEST", I won\'t continue') raise_error(error, conn) #we can go ahead and disable the ports conn.execute('configure terminal') for port in snakearray: conn.execute('interface ' + port) conn.execute('disable') conn.execute('port-name FREE') #conn.execute('clear statistics '+ port) #remove the VLANs remove_vlans(snakearray, conn) quit(conn)
def get_port_dbm_and_type(port, error, conn): port_type_tx_rx = [port, 'unknown', 'None', 'None'] conn.execute('show media ' + port + ' | include Type') port_type_tx_rx[1] = first_match( conn, r'(10GE LR|10GE ER|100GE 10x10|100GE LR4)') if port_type_tx_rx[1] == 'unknown': error.append( port + ' has an unknown port-type, please update the script to include it' ) port_modport = re.split(' ', port) port_module = re.split('/', port_modport[1]) conn.execute('show optic ' + port_module[0] + ' | include ' + port_modport[1] + '[\ t]') port_tx_rx = any_match( conn, r'([-]?[0-9]*\.[0-9]*[ \t]dBm[ \t]+[-]?[0-9]*\.[0-9]*[ \t]dBm)') port_tx_rx = re.split('\s+', str(port_tx_rx)) port_tx = port_tx_rx[0] port_tx = re.split("'", port_tx) port_type_tx_rx[2] = port_tx[1] port_type_tx_rx[3] = port_tx_rx[2] return port_type_tx_rx
def port_status_check (port, conn): conn.execute('show interfaces brief '+ port) Link = first_match(conn, r'(Disab)') if Link == 'Disab': return 1 Link = first_match(conn, r'(Empty)') if Link == 'Empty': return 2 Link = first_match(conn, r'(Down)') if Link == 'Down': return 3 Link = first_match(conn, r'(Up)') if Link == 'Up': Port_State = first_match(conn, r'(Forward)') if Port_State == 'Forward': return 4 #There should be other possibilities than Port_State=Forward right? return 0
def port_status_check(port, conn): conn.execute('show interfaces brief ' + port) Link = first_match(conn, r'(Disab)') if Link == 'Disab': return 1 Link = first_match(conn, r'(Empty)') if Link == 'Empty': return 2 Link = first_match(conn, r'(Down)') if Link == 'Down': return 3 Link = first_match(conn, r'(Up)') if Link == 'Up': Port_State = first_match(conn, r'(Forward)') if Port_State == 'Forward': return 4 #There should be other possibilities than Port_State=Forward right? return 0
def testFirstMatch(self): from Exscript.util.match import first_match string = 'my test' self.assertIsNone(first_match(string, r'aaa')) self.assertEqual(first_match(string, r'\S+'), 'my test') self.assertIsNone(first_match(string, r'(aaa)')) self.assertEqual(first_match(string, r'(\S+)'), 'my') self.assertEqual(first_match(string, r'(aaa) (\S+)'), (None, None)) self.assertEqual(first_match(string, r'(\S+) (\S+)'), ('my', 'test')) self.assertEqual( first_match("24.1632", r'(\d+)\.(\d+)'), ('24', '1632')) self.assertEqual(first_match("24", r'(\d+)\.?(\d+)?'), ('24', None)) multi_line = 'hello\nworld\nhello world' self.assertEqual(first_match(multi_line, r'(he)llo'), 'he')
def remove_vlans(snakearray, conn): for port in snakearray: conn.execute('show vlan ' + port) vlan = first_match(conn, r'(VLAN: [0-9]+)') vlan = re.split(' ', vlan) conn.execute('no vlan ' + vlan[1]) error1 = any_match(conn, r'(Error: Cannot undo the configuration as)') error2 = any_match(conn, r'(session is using this mode\.)') if (error1!=[])and(error2!=[]): quit(conn) raise Exception('Another user is already using this mode, remove him/her/it so we can move on')
def untagged (port, currentvlan, error, conn): currentvlan = str(currentvlan) conn.execute('untagged ' + port) error1 = any_match(conn, r'(Error: ports)') error2 = any_match(conn, r'(are untagged in some user vlans)') if (error1!=[])and(error2!=[]): #Check if the VLAN error was becouse the port is already in currentvlan, if so then leave it there conn.execute('show vlan ' + port) vlan = first_match(conn, r'(VLAN: [0-9]+)') vlan = first_match(vlan, r'([0-9]+)') if (vlan != currentvlan): #Check if the port is already in another snake VLAN 'SNAKE-VLAN', if so then we may replace it conn.execute('show vlan brief | include ' + vlan +'[\ t]') vlan_name = first_match(conn, r'(SNAKE-TEST)') if vlan_name == 'SNAKE-TEST': conn.execute('vlan '+ vlan) conn.execute('no untagged ' + port) conn.execute('vlan ' + currentvlan) conn.execute('untagged ' + port) else: error.append(port + ' is already untagged in ' + vlan)
def untagged(port, currentvlan, error, conn): currentvlan = str(currentvlan) conn.execute('untagged ' + port) error1 = any_match(conn, r'(Error: ports)') error2 = any_match(conn, r'(are untagged in some user vlans)') if (error1 != []) and (error2 != []): #Check if the VLAN error was becouse the port is already in currentvlan, if so then leave it there conn.execute('show vlan ' + port) vlan = first_match(conn, r'(VLAN: [0-9]+)') vlan = first_match(vlan, r'([0-9]+)') if (vlan != currentvlan): #Check if the port is already in another snake VLAN 'SNAKE-VLAN', if so then we may replace it conn.execute('show vlan brief | include ' + vlan + '[\ t]') vlan_name = first_match(conn, r'(SNAKE-TEST)') if vlan_name == 'SNAKE-TEST': conn.execute('vlan ' + vlan) conn.execute('no untagged ' + port) conn.execute('vlan ' + currentvlan) conn.execute('untagged ' + port) else: error.append(port + ' is already untagged in ' + vlan)
def version(self, resp): ret = "" # Get system image name if not isinstance(resp, str): print "No version found" return "" for line in resp.splitlines(): #print "!%s" % line a = first_match(line, r'System image file is "([^\"]*)"', re.I) if a: ret += "!IMAGE: %s\n" % a; continue a = first_match(line, r'^(Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$', re.I) if a[1]: ret += "!IMAGE: Software %s, %s\n" % (a[1], a[2]); continue a = first_match(line, r'^ROM:.*', re.I) if a: ret += "!ROM: %s\n" % a; continue a = first_match(line, r'BOOTLDR:.*', re.I) if a: ret += "!BOOTLDR: %s\n" % a; continue a = first_match(line, r'(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes', re.I) if a[0]: ret += "!TYPE: %s (%s)\n!MEMORY: %s\n" % (a[0], a[1], a[2]) ; continue a = first_match(line, r'^Configuration register is (.*)$') if a: ret += "!CONFREG: %s\n" % a; continue return ret
def remove_vlans(snakearray, conn): for port in snakearray: conn.execute('show vlan ' + port) vlan = first_match(conn, r'(VLAN: [0-9]+)') vlan = re.split(' ', vlan) conn.execute('no vlan ' + vlan[1]) error1 = any_match(conn, r'(Error: Cannot undo the configuration as)') error2 = any_match(conn, r'(session is using this mode\.)') if (error1 != []) and (error2 != []): quit(conn) raise Exception( 'Another user is already using this mode, remove him/her/it so we can move on' )
def testFirstMatch(self): from Exscript.util.match import first_match string = 'my test' self.assert_(first_match(string, r'aaa') is None) self.assert_(first_match(string, r'\S+') == 'my test') self.assert_(first_match(string, r'(aaa)') is None) self.assert_(first_match(string, r'(\S+)') == 'my') self.assert_(first_match(string, r'(aaa) (\S+)') == (None, None)) self.assert_(first_match(string, r'(\S+) (\S+)') == ('my', 'test')) multi_line = 'hello\nworld\nhello world' self.assert_(first_match(multi_line, r'(he)llo') == 'he')
def testFirstMatch(self): from Exscript.util.match import first_match string = 'my test' self.assertTrue(first_match(string, r'aaa') is None) self.assertTrue(first_match(string, r'\S+') == 'my test') self.assertTrue(first_match(string, r'(aaa)') is None) self.assertTrue(first_match(string, r'(\S+)') == 'my') self.assertTrue(first_match(string, r'(aaa) (\S+)') == (None, None)) self.assertTrue(first_match(string, r'(\S+) (\S+)') == ('my', 'test')) multi_line = 'hello\nworld\nhello world' self.assertTrue(first_match(multi_line, r'(he)llo') == 'he')
def dump_config(job, host, conn): """Connect to device, trim config file a bit, write to file""" conn.execute('term len 0') conn.execute('show run') #get the actual hostname of the device hostname = eum.first_match(conn, r'^hostname\s(.+)$') cfg_file = 'c:\\network_configs\\' + hostname.strip() + '.cfg' config = conn.response.splitlines() # a little cleanup for i in range(3): config.pop(i) config.pop(-0) config.pop(-1) # write config to file with open(cfg_file, 'w') as f: for line in config: f.write(line +'\n')
def get_port_dbm_and_type(port, error, conn): port_type_tx_rx = [port, 'unknown', 'None', 'None'] conn.execute('show media '+ port +' | include Type') port_type_tx_rx[1] = first_match(conn, r'(10GE LR|10GE ER|100GE 10x10|100GE LR4)') if port_type_tx_rx[1] == 'unknown': error.append(port + ' has an unknown port-type, please update the script to include it') port_modport = re.split(' ', port) port_module = re.split('/', port_modport[1]) conn.execute('show optic '+ port_module[0] +' | include ' + port_modport[1] + '[\ t]') port_tx_rx = any_match(conn, r'([-]?[0-9]*\.[0-9]*[ \t]dBm[ \t]+[-]?[0-9]*\.[0-9]*[ \t]dBm)') port_tx_rx = re.split('\s+', str(port_tx_rx)) port_tx = port_tx_rx[0] port_tx = re.split("'", port_tx) port_type_tx_rx[2] = port_tx[1] port_type_tx_rx[3] = port_tx_rx[2] return port_type_tx_rx
def backup(self, conn, device): device.make = 'Cisco' self.init(conn) # collect data running_config = self.get_running_config(conn) device.save_config('running-config', running_config) startup_config = self.get_startup_config(conn) device.save_config('startup-config', startup_config) device.hostname = first_match("".join(running_config).replace('\r','\r\n'), r'^hostname (\S+)') device.model, device.serial_number, \ device.type, device.software_version = self.parse_version(conn) device.save()
def port_FREE(switch, username, password, verbose, snakerange): error = [] snakearray = port_extractor(snakerange) conn = login(switch, username, password, verbose) #first check if we may disable all the ports in the snake-array, is there a 'SNAKEPORT' in its port-name? for port in snakearray: conn.execute('show interfaces '+ port + ' | include Port name') maydisable = first_match(conn, r'(SNAKETEST:)') if maydisable != 'SNAKETEST:': error.append('interface ' + port + ' has no port-name with "SNAKETEST", I won\'t continue') raise_error(error, conn) #we can go ahead and disable the ports conn.execute('configure terminal') for port in snakearray: conn.execute('interface ' + port) conn.execute('disable') conn.execute('port-name FREE') #conn.execute('clear statistics '+ port) #remove the VLANs remove_vlans(snakearray, conn) quit(conn)
def parse_version(self, conn): conn.execute('show version') version = first_match(conn, r'^(?:Cisco )?IOS.+Version (\S[^\s,]+)') if not version: version = first_match(conn, r'^Version\s+V(\d+\.\d+\.\d+') type = "Router" if first_match(conn, r'\b(cat|(WS|ME)-C)\d{4}|catalyst|CIGESM', re.M | re.I): type = "Switch" if first_match(conn, r'\bC1200\b|\bAIR'): type = "Wireless Access Point" model = first_match(conn, r'cisco ((?:WS-C|Cat|AS|C|VG)?\d{3,4}\S*\b)\S*\b', re.M | re.I) serial_number = first_match(conn, r'^Processor\s+board\s+ID\s+(\w+)') return [model, serial_number, type, version]
def extract( host, username, tar_file, cd_dir, timeout=45, key_filename=None, verbosity=0, parallel_count=5, ): """Extract and start lab""" log.debug('Extracting and starting lab on %s' % host) log.info('Extracting and starting Netkit lab') from Exscript import Account from Exscript.util.start import start from Exscript.util.match import first_match from Exscript import PrivateKey from Exscript.protocols.Exception import InvalidCommandException messaging = ank_messaging def starting_host(protocol, index, data): log.info('Starting %s' % data.group(1)) def lab_started(protocol, index, data): log.info('Lab started on %s' % host) def make_not_found(protocol, index, data): log.warning( 'Make not installed on remote host %s. Please install make and retry.' % host) return def process_vlist(response): """Obtain VM to PID listing: required if terminating a numeric VM""" # TODO: could process using textfsm template vm_to_pid = {} for line in response.splitlines(): match = re.match(r'^\w+\s+(\w+)\s+(\d+)', line) if match: vm = match.group(1) pid = match.group(2) vm_to_pid[vm] = pid return vm_to_pid def start_lab(thread, host, conn): conn.set_timeout(timeout) conn.add_monitor(r'Starting "(\w+)"', starting_host) conn.add_monitor(r'The lab has been started', lab_started) lab_vlist = [] # conn.add_monitor(r'Virtual machine "((\S*_*)+)" is already running. Please', already_running_b) conn.add_monitor(r'make: not found', make_not_found) # conn.data_received_event.connect(data_received) conn.execute('cd %s' % cd_dir) conn.execute('lcrash -k') conn.execute('lclean') conn.execute('cd') # back to home directory tar file copied to conn.execute('tar -xzf %s' % tar_file) conn.execute('cd %s' % cd_dir) conn.execute('linfo') linfo_response = str(conn.response) vm_list = [] for line in linfo_response.splitlines(): if 'The lab is made up of' in line: open_bracket = line.index('(') close_bracket = line.index(')') vm_list = line[open_bracket + 1:close_bracket] vm_list = vm_list.split() log.info('The lab contains VMs %s' % ', '.join(vm_list)) # now check if any vms are still running conn.execute('vlist') response = str(conn.response) lab_vlist = process_vlist(response) for virtual_machine in lab_vlist: if virtual_machine in vm_list: if virtual_machine.isdigit: # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID) crash_id = lab_vlist.get(virtual_machine) else: crash_id = virtual_machine # use name if crash_id: # crash_id may not be set, if machine not present in initial vlist, if so then ignore log.info('Stopping running VM %s' % virtual_machine) conn.execute('vcrash %s' % crash_id) conn.execute('vlist') conn.execute('lclean') start_command = 'lstart -p%s -o --con0=none' % parallel_count lab_is_started = False while lab_is_started == False: try: log.info('Starting lab') conn.execute(start_command) except InvalidCommandException, error: error_string = str(error) if 'already running' in error_string: conn.execute('vlist') response = str(conn.response) lab_vlist = process_vlist(response) running_vms = [] for line in error_string.splitlines(): if 'already running' in line: running_vm = line.split('"')[1] running_vms.append(running_vm) for virtual_machine in running_vms: if virtual_machine.isdigit: # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID) crash_id = lab_vlist.get(virtual_machine) else: crash_id = virtual_machine # use name if crash_id: # crash_id may not be set, if machine not present in initial vlist, if so then ignore log.info('Stopping running VM %s' % virtual_machine) conn.execute('vcrash %s' % crash_id) time.sleep(1) else: # conn.execute(start_command) lab_is_started = True first_match(conn, r'^The lab has been started') log.info('Lab started' ) # TODO: make this captured - need to debug capturing conn.send('exit')
def extract(host, username, tar_file, cd_dir, timeout = 30, key_filename = None): """Extract and start lab""" from Exscript import Account from Exscript.util.start import start from Exscript.util.match import first_match from Exscript import PrivateKey from Exscript.protocols.Exception import InvalidCommandException import pika import json www_connection = pika.BlockingConnection(pika.ConnectionParameters( host='115.146.94.68')) www_channel = www_connection.channel() www_channel.exchange_declare(exchange='www', type='direct') def starting_host(protocol, index, data): #print "Starting", data.group(index) log.info(data.group(index)) body = {"starting": data.group(index)} www_channel.basic_publish(exchange='www', routing_key = "client", body= json.dumps(body)) pass #TODO: send to rabbitmq def lab_started(protocol, index, data): print "Lab started" def do_something(thread, host, conn): conn.set_timeout(timeout) conn.add_monitor(r'Starting (\S+)', starting_host) conn.add_monitor(r'The lab has been started', lab_started) #conn.data_received_event.connect(data_received) conn.execute('cd %s' % cd_dir) conn.execute('lcrash -k') conn.execute("lclean") conn.execute('cd') # back to home directory tar file copied to conn.execute('tar -xzf %s' % tar_file) conn.execute('cd %s' % cd_dir) conn.execute('vlist') conn.execute("lclean") log.info("Starting lab") start_command = 'lstart -p5 -o --con0=none' try: conn.execute(start_command) except InvalidCommandException, error: if "already running" in str(error): time.sleep(1) #print "Already Running" #TODO: handle appropriately #print "Halting previous lab" #conn.execute("vclean -K") #print "Halted previous lab" #conn.execute("vstart taptunnelvm --con0=none --eth0=tap,172.16.0.1,172.16.0.2") # TODO: don't hardcode this #print "Starting lab" conn.execute(start_command) first_match(conn, r'^The lab has been started') conn.send("exit")
def extract( host, username, tar_file, cd_dir, timeout=45, key_filename=None, verbosity=0, parallel_count=5, ): """Extract and start lab""" log.debug('Extracting and starting lab on %s' % host) log.info('Extracting and starting Netkit lab') from Exscript import Account from Exscript.util.start import start from Exscript.util.match import first_match from Exscript import PrivateKey from Exscript.protocols.Exception import InvalidCommandException messaging = ank_messaging def starting_host(protocol, index, data): log.info('Starting %s' % data.group(1)) def lab_started(protocol, index, data): log.info('Lab started on %s' % host) def make_not_found(protocol, index, data): log.warning('Make not installed on remote host %s. Please install make and retry.' % host) return def process_vlist(response): """Obtain VM to PID listing: required if terminating a numeric VM""" # TODO: could process using textfsm template vm_to_pid = {} for line in response.splitlines(): match = re.match(r'^\w+\s+(\w+)\s+(\d+)', line) if match: vm = match.group(1) pid = match.group(2) vm_to_pid[vm] = pid return vm_to_pid def start_lab(thread, host, conn): conn.set_timeout(timeout) conn.add_monitor(r'Starting "(\w+)"', starting_host) conn.add_monitor(r'The lab has been started', lab_started) lab_vlist = [] # conn.add_monitor(r'Virtual machine "((\S*_*)+)" is already running. Please', already_running_b) conn.add_monitor(r'make: not found', make_not_found) # conn.data_received_event.connect(data_received) conn.execute('cd %s' % cd_dir) conn.execute('lcrash -k') conn.execute('lclean') conn.execute('cd') # back to home directory tar file copied to conn.execute('tar -xzf %s' % tar_file) conn.execute('cd %s' % cd_dir) conn.execute('linfo') linfo_response = str(conn.response) vm_list = [] for line in linfo_response.splitlines(): if 'The lab is made up of' in line: open_bracket = line.index('(') close_bracket = line.index(')') vm_list = line[open_bracket + 1:close_bracket] vm_list = vm_list.split() log.info('The lab contains VMs %s' % ', '.join(vm_list)) # now check if any vms are still running conn.execute('vlist') response = str(conn.response) lab_vlist = process_vlist(response) for virtual_machine in lab_vlist: if virtual_machine in vm_list: if virtual_machine.isdigit: # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID) crash_id = lab_vlist.get(virtual_machine) else: crash_id = virtual_machine # use name if crash_id: # crash_id may not be set, if machine not present in initial vlist, if so then ignore log.info('Stopping running VM %s' % virtual_machine) conn.execute('vcrash %s' % crash_id) conn.execute('vlist') conn.execute('lclean') start_command = 'lstart -p%s -o --con0=none' % parallel_count lab_is_started = False while lab_is_started == False: try: log.info('Starting lab') conn.execute(start_command) except InvalidCommandException, error: error_string = str(error) if 'already running' in error_string: conn.execute('vlist') response = str(conn.response) lab_vlist = process_vlist(response) running_vms = [] for line in error_string.splitlines(): if 'already running' in line: running_vm = line.split('"')[1] running_vms.append(running_vm) for virtual_machine in running_vms: if virtual_machine.isdigit: # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID) crash_id = lab_vlist.get(virtual_machine) else: crash_id = virtual_machine # use name if crash_id: # crash_id may not be set, if machine not present in initial vlist, if so then ignore log.info('Stopping running VM %s' % virtual_machine) conn.execute('vcrash %s' % crash_id) time.sleep(1) else: # conn.execute(start_command) lab_is_started = True first_match(conn, r'^The lab has been started') log.info('Lab started') # TODO: make this captured - need to debug capturing conn.send('exit')