def get_host_info(htype='1', netint='1', netmac='1'): "Populate the host info caches" if htype == '1': get_type_cached(env.host_string) if netint == '1': get_netint_cached(env.host_string, int_no=-1) get_netint_windump_cached(env.host_string, int_no=-1) get_netint_cached(env.host_string, int_no=-1, internal_int='0') get_netint_windump_cached(env.host_string, int_no=-1, internal_int='0') if netmac == '1': get_netmac_cached(env.host_string)
def init_os(file_prefix='', os_list='', force_reboot='0', do_power_cycle='0', boot_timeout='100', local_dir='.', linux_kern_router='3.10.18-vanilla-10000hz', linux_kern_hosts='3.9.8-desktop-web10g', tftp_server='10.1.1.11:8080', mac_list=''): "Boot host with selected operating system" _boot_timeout = int(boot_timeout) if _boot_timeout < 60: warn('Boot timeout value too small, using 60 seconds') _boot_timeout = '60' host_os_vals = os_list.split(',') if len(env.all_hosts) < len(host_os_vals): abort('Number of OSs specified must be the same as number of hosts') # duplicate last one until we reach correct length while len(host_os_vals) < len(env.all_hosts): host_os_vals.append(host_os_vals[-1]) host_mac = {} if mac_list != '': mac_vals = mac_list.split(',') if len(env.all_hosts) != len(mac_vals): abort('Must specify one MAC address for each host') # create a dictionary host_mac = dict(zip(env.all_hosts, mac_vals)) # get type of current host if possible # XXX try to suppress Fabric exception traceback in case host is not # accessible, but doesn't seem to work properly with settings(hide('debug', 'warnings'), warn_only=True): htype = get_type_cached(env.host_string) if type(htype) == NetworkError: # host not accessible, set htype to unknown htype = '?' # get dictionary from host and OS lists host_os = dict(zip(env.all_hosts, host_os_vals)) # os we want target_os = host_os.get(env.host_string, '') kern = '' target_kern = '' if target_os == 'Linux': if env.host_string in config.TPCONF_router: target_kern = linux_kern_router else: target_kern = linux_kern_hosts if htype == 'Linux': kern = run('uname -r') else: kern = '?' if target_kern == 'running' or target_kern == 'current': if htype == 'Linux': target_kern = kern else: warn('Host not running Linux, ignoring "running" or "current"') if target_os != '' and (force_reboot == '1' or target_os != htype or target_kern != kern): # write pxe config file pxe_template = config.TPCONF_script_path + \ '/conf-macaddr_xx\:xx\:xx\:xx\:xx\:xx.ipxe.in' # if we have a mac address specified use it, otherwise try to automatically # get the mac address if env.host_string in host_mac: mac = host_mac[env.host_string] else: mac = get_netmac_cached(env.host_string) file_name = 'conf-macaddr_' + mac + '.ipxe' hdd_partition = '' if target_os == 'CYGWIN': hdd_partition = '(hd0,0)' elif target_os == 'Linux': hdd_partition = '(hd0,1)' elif target_os == 'FreeBSD': hdd_partition = '(hd0,2)' try: hdd_partition = config.TPCONF_os_partition[target_os] except AttributeError: pass if target_os == 'Linux': # could remove the if, but might need in future if we specify # different options for router and hosts if env.host_string in config.TPCONF_router: config_str = 'root ' + hdd_partition + '; kernel \/boot\/vmlinuz-' + \ target_kern + ' splash=0 quiet showopts; ' + \ 'initrd \/boot\/initrd-' + target_kern else: config_str = 'root ' + hdd_partition + '; kernel \/boot\/vmlinuz-' + \ target_kern + ' splash=0 quiet showopts; ' + \ 'initrd \/boot\/initrd-' + target_kern elif target_os == 'CYGWIN': if env.host_string in config.TPCONF_router: abort('Router has no Windows') config_str = 'root ' + hdd_partition + '; chainloader +1' elif target_os == 'FreeBSD': config_str = 'root ' + hdd_partition + '; chainloader +1' elif target_os == 'Darwin': pass else: abort('Unknown OS %s' % target_os) if force_reboot == '1': puts('Forced reboot (TPCONF_force_reboot = \'1\')') puts('Switching %s from OS %s %s to OS %s %s' % (env.host_string, htype, kern, target_os, target_kern)) if htype != 'Darwin': # no PXE booting for Macs local( 'cat %s | sed -e "s/@CONFIG@/%s/" | sed -e "s/@TFTPSERVER@/%s/" > %s' % (pxe_template, config_str, tftp_server, file_name)) # make backup of current file if not exists yet full_file_name = config.TPCONF_tftpboot_dir + '/' + file_name full_file_name_backup = config.TPCONF_tftpboot_dir + \ '/' + file_name + '.bak' with settings(warn_only=True): local('mv -f %s %s' % (full_file_name, full_file_name_backup)) local('rm -f %s' % full_file_name) # XXX should combine the next two into one shell command to make it # more atomic local('cp %s %s' % (file_name, config.TPCONF_tftpboot_dir)) local('chmod a+rw %s' % full_file_name) if file_prefix != '': file_name2 = local_dir + '/' + file_prefix + '_' + file_name local('mv %s %s' % (file_name, file_name2)) # reboot with settings(warn_only=True): if htype == '?': # we cannot login to issue shutdown command, so power cycle and hope # for the best execute(power_cycle) elif htype == 'Linux' or htype == 'FreeBSD' or htype == 'Darwin': run('shutdown -r now', pty=False) elif htype == 'CYGWIN': run('shutdown -r -t 0', pty=False) # give some time to shutdown puts('Waiting for reboot...') time.sleep(60) # wait until up t = 60 while t <= _boot_timeout: # ret = local('ping -c 1 %s' % env.host_string) # ping works before # ssh and can't ping from inside jail with settings(warn_only=True): try: ret = run('echo waiting for OS %s to start' % target_os, timeout=2, pty=False) if ret.return_code == 0: break except: pass time.sleep(8) t += 10 if t > _boot_timeout and do_power_cycle == '1': # host still not up, may be hanging so power cycle it puts('Power cycling host...') execute(power_cycle) puts('Waiting for reboot...') time.sleep(60) # wait until up t = 60 while t <= _boot_timeout: # ret = local('ping -c 1 %s' % env.host_string) # ping works # before ssh and can't ping from inside jail with settings(warn_only=True): try: ret = run('echo waiting for OS %s to start' % target_os, timeout=2, pty=False) if ret.return_code == 0: break except: pass time.sleep(8) t += 10 # finally check if host is up again with desired OS # XXX if the following fails because we can't connect to host Fabric # will crash with weird error (not super important since we would abort # anyway but annoying) htype = execute(get_type, hosts=[env.host_string])[env.host_string] if target_os == 'Linux': kern = run('uname -r') if htype == target_os and kern == target_kern: puts('Host %s running OS %s %s' % (env.host_string, target_os, target_kern)) else: abort('Error switching %s to OS %s %s' % (env.host_string, target_os, target_kern)) else: if target_os == '': target_os = htype puts('Leaving %s as OS %s %s' % (env.host_string, target_os, target_kern))
def init_os(file_prefix='', os_list='', force_reboot='0', do_power_cycle='0', boot_timeout='100', local_dir='.', linux_kern_router='3.10.18-vanilla-10000hz', linux_kern_hosts='3.9.8-desktop-web10g', tftp_server='10.1.1.11:8080', mac_list=''): "Boot host with selected operating system" _boot_timeout = int(boot_timeout) if _boot_timeout < 60: warn('Boot timeout value too small, using 60 seconds') _boot_timeout = '60' host_os_vals = os_list.split(',') if len(env.all_hosts) < len(host_os_vals): abort('Number of OSs specified must be the same as number of hosts') # duplicate last one until we reach correct length while len(host_os_vals) < len(env.all_hosts): host_os_vals.append(host_os_vals[-1]) host_mac = {} if mac_list != '': mac_vals = mac_list.split(',') if len(env.all_hosts) != len(mac_vals): abort('Must specify one MAC address for each host') # create a dictionary host_mac = dict(zip(env.all_hosts, mac_vals)) # get type of current host if possible # XXX try to suppress Fabric exception traceback in case host is not # accessible, but doesn't seem to work properly with settings(hide('debug', 'warnings'), warn_only=True): htype = get_type_cached(env.host_string) if type(htype) == NetworkError: # host not accessible, set htype to unknown htype = '?' # get dictionary from host and OS lists host_os = dict(zip(env.all_hosts, host_os_vals)) # os we want target_os = host_os.get(env.host_string, '') kern = '' target_kern = '' if target_os == 'Linux': if env.host_string in config.TPCONF_router: target_kern = linux_kern_router else: target_kern = linux_kern_hosts if htype == 'Linux': kern = run('uname -r') else: kern = '?' if target_kern == 'running' or target_kern == 'current': if htype == 'Linux': target_kern = kern else: warn('Host not running Linux, ignoring "running" or "current"') if target_os != '' and ( force_reboot == '1' or target_os != htype or target_kern != kern): # write pxe config file pxe_template = config.TPCONF_script_path + \ '/conf-macaddr_xx\:xx\:xx\:xx\:xx\:xx.ipxe.in' # if we have a mac address specified use it, otherwise try to automatically # get the mac address if env.host_string in host_mac: mac = host_mac[env.host_string] else: mac = get_netmac_cached(env.host_string) file_name = 'conf-macaddr_' + mac + '.ipxe' hdd_partition = '' if target_os == 'CYGWIN': hdd_partition = '(hd0,0)' elif target_os == 'Linux': hdd_partition = '(hd0,1)' elif target_os == 'FreeBSD': hdd_partition = '(hd0,2)' try: hdd_partition = config.TPCONF_os_partition[target_os] except AttributeError: pass if target_os == 'Linux': # could remove the if, but might need in future if we specify # different options for router and hosts if env.host_string in config.TPCONF_router: config_str = 'root ' + hdd_partition + '; kernel \/boot\/vmlinuz-' + \ target_kern + ' splash=0 quiet showopts; ' + \ 'initrd \/boot\/initrd-' + target_kern else: config_str = 'root ' + hdd_partition + '; kernel \/boot\/vmlinuz-' + \ target_kern + ' splash=0 quiet showopts; ' + \ 'initrd \/boot\/initrd-' + target_kern elif target_os == 'CYGWIN': if env.host_string in config.TPCONF_router: abort('Router has no Windows') config_str = 'root ' + hdd_partition + '; chainloader +1' elif target_os == 'FreeBSD': config_str = 'root ' + hdd_partition + '; chainloader +1' elif target_os == 'Darwin': pass else: abort('Unknown OS %s' % target_os) if force_reboot == '1': puts('Forced reboot (TPCONF_force_reboot = \'1\')') puts( 'Switching %s from OS %s %s to OS %s %s' % (env.host_string, htype, kern, target_os, target_kern)) if htype != 'Darwin': # no PXE booting for Macs local( 'cat %s | sed -e "s/@CONFIG@/%s/" | sed -e "s/@TFTPSERVER@/%s/" > %s' % (pxe_template, config_str, tftp_server, file_name)) # make backup of current file if not exists yet full_file_name = config.TPCONF_tftpboot_dir + '/' + file_name full_file_name_backup = config.TPCONF_tftpboot_dir + \ '/' + file_name + '.bak' with settings(warn_only=True): local('mv -f %s %s' % (full_file_name, full_file_name_backup)) local('rm -f %s' % full_file_name) # XXX should combine the next two into one shell command to make it # more atomic local('cp %s %s' % (file_name, config.TPCONF_tftpboot_dir)) local('chmod a+rw %s' % full_file_name) if file_prefix != '': file_name2 = local_dir + '/' + file_prefix + '_' + file_name local('mv %s %s' % (file_name, file_name2)) # reboot with settings(warn_only=True): if htype == '?': # we cannot login to issue shutdown command, so power cycle and hope # for the best execute(power_cycle) elif htype == 'Linux' or htype == 'FreeBSD' or htype == 'Darwin': run('shutdown -r now', pty=False) elif htype == 'CYGWIN': run('shutdown -r -t 0', pty=False) # give some time to shutdown puts('Waiting for reboot...') time.sleep(60) # wait until up t = 60 while t <= _boot_timeout: # ret = local('ping -c 1 %s' % env.host_string) # ping works before # ssh and can't ping from inside jail with settings(warn_only=True): try: ret = run( 'echo waiting for OS %s to start' % target_os, timeout=2, pty=False) if ret.return_code == 0: break except: pass time.sleep(8) t += 10 if t > _boot_timeout and do_power_cycle == '1': # host still not up, may be hanging so power cycle it puts('Power cycling host...') execute(power_cycle) puts('Waiting for reboot...') time.sleep(60) # wait until up t = 60 while t <= _boot_timeout: # ret = local('ping -c 1 %s' % env.host_string) # ping works # before ssh and can't ping from inside jail with settings(warn_only=True): try: ret = run( 'echo waiting for OS %s to start' % target_os, timeout=2, pty=False) if ret.return_code == 0: break except: pass time.sleep(8) t += 10 # finally check if host is up again with desired OS # XXX if the following fails because we can't connect to host Fabric # will crash with weird error (not super important since we would abort # anyway but annoying) htype = execute(get_type, hosts=[env.host_string])[env.host_string] if target_os == 'Linux': kern = run('uname -r') if htype == target_os and kern == target_kern: puts( 'Host %s running OS %s %s' % (env.host_string, target_os, target_kern)) else: abort( 'Error switching %s to OS %s %s' % (env.host_string, target_os, target_kern)) else: if target_os == '': target_os = htype puts( 'Leaving %s as OS %s %s' % (env.host_string, target_os, target_kern))