How to use remove_hosts method in autotest

Best Python code snippet using autotest_python

__init__.py

Source:__init__.py Github

copy

Full Screen

1from __future__ import absolute_import2import sys3import time4import re5import threading6import os7from mesadb.network import SSH, adapterpool8import socket, os, os.path9from optparse import OptionParser10from mesadb.config import DBinclude11from mesadb.tools import DBfunctions12from mesadb.engine import adminExec13from mesadb.ui import commandLineCtrl14from mesadb.network.ssh_auth import SshAuth15from mesadb.config.Configurator import Configurator16from mesadb.network import SystemProfileFactory17from mesadb.upgrade import IntegrateSpread18import types19import getpass20from mesadb.log.InstallLogger import InstallLogger21import math22import hashlib23from mesadb.network.adapters import adapter24import mesadb.shared.util as util25import mesadb.utils.ssl26import mesadb.install.silent27from mesadb.install import status28import mesadb.utils.ssh_keygen29#30g_install_status = None31def switch_status(new_status, options):32 global g_install_status33 if g_install_status is not None:34 g_install_status.printSuccess()35 g_install_status = new_status36 g_install_status.setOptions(options)37 g_install_status.printEnter()38def empty_string(x, strip=False):39 if strip:40 return x is None or len(x.strip()) == 041 else:42 return x is None or len(x) == 043# 检查默认的 shell 脚本44def check_default_shell(fullhostname_list, installerSSH):45 installerSSH.setHosts(fullhostname_list)46 Status, res = installerSSH.execute("echo $SHELL", hide=True)47 wrong_shells = {}48 for k,v in res.items():49 if "bash" not in v[1][0]:50 wrong_shells[k]=v[1][0]51 if len(wrong_shells)>0:52 print "Error: Default shell on the following nodes are not bash. Default shell must be set to bash."53 for k,v in wrong_shells.items():54 print k,v55 print "Exiting..."56 sys.exit(1)57 else:58 print "Default shell on nodes:"59 for k,v in res.items():60 print k,v[1][0]61# 判断是否为同一个主机62def are_hosts_the_same( a, b ):63 # 通过地址获得主机信息,然后比较如下信息: hostname, aliaslist, ipaddrlist64 # 如果a,b之间上述属性是相同的,那么可以确定是相同的主机信息.65 # 将a,b条目值设置在列表中.66 a_entries = set([ a[0] ] + a[1] + a[2])67 b_entries = set([ b[0] ] + b[1] + b[2])68 # 设置交集为空?69 return len(a_entries & b_entries) > 070# 执行IntegrateSpread配置文件中的upgrade_integrate_spread方法71def run_upgrades(running_as, user, executor):72 return IntegrateSpread.upgrade_integrate_spread(running_as,user,executor)73#后处理选项74def _post_process_options(options):75 prog = 'update_mesadb' if options.update_mesadb else 'install_mesadb'76 #77 # 后处理选项78 #79 if options.record_to is not None and options.silent_config is not None:80 print "\nError: Cannot provide and read silent config at the same time"81 sys.exit(1)82 if options.record_to is not None:83 mesadb.install.silent.record_options(options)84 sys.exit(0)85 if options.silent_config is not None:86 if not mesadb.install.silent.process_config_file(options.silent_config, options):87 print "\nError: Error parsing %s. See above." % options.silent_config88 sys.exit(1)89 # 命令行参数-S的值 (--spread_reconfig) 为 'default' 或者为 ipaddress90 if options.spread_subnet is not None and options.spread_subnet!='default':91 try:92 socket.inet_pton(socket.AF_INET, options.spread_subnet)93 except socket.error as err:94 print "\nError: Invalid value %s for --control-network (-S)" % options.spread_subnet95 sys.exit(1)96 if options.spread_count is not None and options.spread_count not in ['off','default']:97 try:98 int(options.spread_count)99 except ValueError as err:100 print "\nError: Invalid value '%s' for --large-cluster (-2)" % options.spread_count101 sys.exit(1)102 # 更改 rpm_file_name 到一个绝对路径, 同时检查此文件.103 if empty_string(options.rpm_file_name):104 options.rpm_file_name = None105 else:106 options.rpm_file_name = os.path.abspath(options.rpm_file_name)107 if not os.path.exists( options.rpm_file_name ):108 print "Invalid path for rpm file: %s" % options.rpm_file_name109 sys.exit(1)110 # 不能同时添加和删除主机(-A or -R)111 if (options.add_hosts or options.remove_hosts) and options.hosts:112 print "Error: Cannot both install and modify the cluster."113 print "Hint: Do not use --hosts (-s) while using --add-hosts (-A) or --remove-hosts (-R)"114 sys.exit(1)115 # --clean (-C)不能与--add-hosts (-A)和--remove-hosts (-R)同时使用116 if (options.add_hosts or options.remove_hosts) and options.clean:117 print "The --clean option cannot be used with --add-hosts (-A) or --remove-hosts (-R) options\n"118 sys.exit(1)119 # --clean (-C)不能与 update_mesadb 同时使用120 if options.update_mesadb and options.clean:121 print "The --clean option cannot be used with update_mesadb\n"122 sys.exit(1)123 # 如果用户指定了一个ssh identity, 确保它是有效的, 同时是无密码保护的.124 if options.ssh_identity is not None:125 keygen = mesadb.utils.ssh_keygen126 if keygen.ssh_keygen_bin() is None:127 print "Warning: ssh-keygen cannot be found on this system. You may experience problems using the --ssh-identity option."128 elif not keygen.is_passwordless_private_key(options.ssh_identity):129 print "Error: %s is not a passwordless SSH private key or could not be accessed." % options.ssh_identity130 print "Hint: --ssh-identity can only accept unprotected private keys. Use an SSH agent for password protected keys."131 sys.exit(1)132 if options.mesadb_dba_user_dir is None:133 options.mesadb_dba_user_dir = "/home/%s" % options.mesadb_dba_user134 if options.data_dir is None:135 options.data_dir = options.mesadb_dba_user_dir136 # mesadb installer 通常以 root 权限来运行.137 if os.geteuid()!=0 and len(os.environ.get('_VERT_ROOT_OVERRIDE', ''))==0:138 print "%s must be run as root." % prog139 print "Hint: Try again with su or sudo"140 sys.exit(1)141 # 安装 openssl 包142 if not mesadb.utils.ssl.have_openssl():143 print "Error: Unable to find 'openssl'. Please install this package before proceeding."144 sys.exit(1)145def _get_install_hosts(options, siteDict):146 """ 给出本地主机和已经添加,维护,删除的主机列表.147 148 返回如下值 (local_host, add_hosts, keep_hosts, remove_hosts)149 local_host: 本地主机信息150 add_hosts: 添加到集群的主机列表151 keep_hosts: 在集群中的主机列表152 remove_hosts: 从集群删除的主机列表153 154 IMPORTANT: 当执行--clean 命令后, remove_hosts 和 kee_hosts 列表为空.155 这些主机并没有真正被删除, 而是在列表中清除.156 每个主机的对象包括: (ipaddress, hostnames, addresses)157 ipaddress: IP地址158 hostnames: 主机名列表159 addresses: IP地址列表160 """161 def findHost(host, collection):162 # 在主机列表中查找某主机,主机和主机列表通过主机名来进行更正.163 for x in collection:164 if are_hosts_the_same(host, x):165 return True166 return False167 # 主机更正封装器168 def hostFixupWrapper(hoststring, argument):169 hostparts = [ x.strip() for x in hoststring.split(',') ]170 hostparts = [ x for x in hostparts if len(x) != 0 ]171 if len(hostparts) == 0:172 return []173 print "\nMapping hostnames in %s to addresses..." % argument174 addresses = []175 # 解析主机到单个IP176 for host in hostparts:177 try:178 address = util.resolve_to_one_ip(host)179 except StandardError as err:180 print "\t%s" % err181 print "\tError: Unable to resolve %r" % host182 sys.exit(1)183 if host != address:184 # only showing resolutions that aren't IP literals.185 print "\t%-30s => %s" % (host, address)186 187 # 追加IP地址到地址列表188 addresses.append(address)189 # 在列表中检测重复地址190 seen = set()191 duplicates = False192 for address in addresses:193 if address in seen:194 print "\tError: Duplicate address: %s" % address195 duplicates = True196 else:197 seen.add(address)198 if duplicates:199 sys.exit(1)200 return DBfunctions.hostname_fixup(addresses)201 # END hostFixupWrapper202 add_hosts = [] # 用 --add-hosts 指定主机列表203 remove_hosts = [] # 用 --remove-hosts(not via --clean) 指定主机列表204 opt_hosts = [] # 用 --hosts指定主机列表205 existing_hosts = [] # 存在于集群中的主机列表206 keep_hosts = [] # 存在于集群中的活跃主机列表207 if(options.add_hosts and len(options.add_hosts) > 0 ):208 add_hosts = hostFixupWrapper(options.add_hosts, '--add-hosts (-A)')209 if(options.remove_hosts and len(options.remove_hosts) > 0 ):210 remove_hosts = hostFixupWrapper(options.remove_hosts, '--remove-hosts (-R)')211 if(options.hosts and len(options.hosts) > 0 ):212 opt_hosts = hostFixupWrapper(options.hosts, '--hosts (-s)')213 existing_hosts = set([ x[1] for x in siteDict.values() ])214 existing_hosts = DBfunctions.hostname_fixup(existing_hosts)215 assert not options.clean or len(remove_hosts) == 0, \216 "Cannot use --clean and --remove-hosts together"217 # 验证已经删除的主机,是集群内的主机.218 for x in remove_hosts:219 if not findHost(x, existing_hosts):220 hostlist = ', '.join([ y[0] for y in existing_hosts ])221 print "Error: Unable to remove host %s: not part of the cluster " % x[0]222 print "Hint: Valid hosts are: %s" % hostlist223 sys.exit(1)224 # 验证已经添加的主机,不是集群内的主机.225 for x in add_hosts:226 if findHost(x, existing_hosts):227 hostlist = ', '.join([ y[0] for y in existing_hosts ])228 print "Error: Unable to add host %s: already part of the cluster " % x[0]229 print "Hint: Existing hosts are: %s" % hostlist230 sys.exit(1)231 # 生成集群内活跃节点的列表232 if options.clean:233 keep_hosts = []234 else:235 keep_hosts = [ x for x in existing_hosts if not findHost(x, remove_hosts) ]236 # 早期安全检查.237 assert len(opt_hosts) == 0 or len(add_hosts) == 0, \238 "Cannot use --hosts and --add-hosts togther"239 assert len(opt_hosts) == 0 or len(remove_hosts) == 0, \240 "Cannot use --hosts and --remove-hosts togther"241 # 精确匹配选项中的主机列表和集群中的主机列表.242 if len(opt_hosts) > 0 and len(keep_hosts) > 0:243 fail_msgs = []244 for x in opt_hosts:245 if not findHost(x, keep_hosts):246 fail_msgs.append("\t%s in --hosts but not in cluster." % x[0])247 for x in keep_hosts:248 if not findHost(x, opt_hosts):249 fail_msgs.append("\t%s in cluster but not in --hosts." % x[0])250 if len(fail_msgs) > 0:251 print "Error: A cluster exists but does not match the provided --hosts"252 for msg in fail_msgs:253 print msg254 print "Hint: omit --hosts for existing clusters. To change a cluster use --add-hosts or --remove-hosts."255 sys.exit(1)256 if len(keep_hosts) == 0:257 # 从--hosts 移动主机到 --add-hosts.258 if len(opt_hosts) > 0:259 assert len(add_hosts) == 0260 add_hosts = list(opt_hosts)261 opt_hosts = []262 # 用户必须指定一个主机 (no default localhost)263 if len(add_hosts) == 0:264 print "Error: No machines will be included in the cluster!"265 print "Hint: provide --hosts."266 sys.exit(1)267 # 防止localhost(loopback)主机称为'2+node'集群的节点.268 if len(keep_hosts) + len(add_hosts) >= 2:269 if "127.0.0.1" in [ x[0] for x in keep_hosts ]:270 print """\271Error: Existing single-node localhost (loopback) cluster cannot be expanded272Hint: Move cluster to external address first."""273 sys.exit(1)274 if "127.0.0.1" in [ x[0] for x in add_hosts ]:275 print """\276Error: Cannot add localhost (loopback) to an existing cluster.277Hint: Use an external address."""278 sys.exit(1)279 # '标准'主机名列表280 all_hosts = add_hosts + keep_hosts + remove_hosts281 local_host = None282 for x in all_hosts:283 if DBfunctions.IsLocalHost(x[0]):284 local_host = x285 break # count on there being no duplicates, as previously checked286 if local_host is None:287 print "Error: cannot find which cluster host is the local host."288 print "Hint: Is this node in the cluster? Did its IP address change?"289 sys.exit(1)290 # 不要从集群中移除localhost主机,291 # 建议在另外的主机上从集群中移除localhost.292 if findHost(local_host, remove_hosts):293 print "Error: Cannot remove the local host (%s) from the cluster." % local_host[0]294 print "Hint: Use another host in the cluster to remove this host."295 sys.exit(1)296 return (local_host, add_hosts, keep_hosts, remove_hosts)297def _legacy_get_install_hosts(options, siteDict):298 """Glue!"""299 (local_host, add_hosts, keep_hosts, remove_hosts) = \300 _get_install_hosts(options, siteDict)301 def to_hostnames(hosts):302 return [x[0] for x in hosts]303 return (local_host[0], to_hostnames(add_hosts + keep_hosts + remove_hosts),304 to_hostnames(add_hosts), add_hosts,305 to_hostnames(remove_hosts), remove_hosts,306 to_hostnames(keep_hosts), keep_hosts)307# 如果指定了control-subnet, 确保它匹配主机.308def spread_subnet_is_usable(bcastaddr, profiles):309 "检查是否control-subnet的broadcast address 正常工作"310 mismatches = []311 for (host, machine) in profiles.iteritems():312 if not machine.has_broadcast(bcastaddr):313 mismatches.append(machine)314 if len(mismatches) == len(profiles):315 print "Error: It appears that --control-network %r is invalid" % bcastaddr316 print "Hint: Is this a broadcast address found on any machine?"317 return False318 if len(mismatches) > 0:319 print "Warning: Some machines do not have an interface with broadcast %r (--control-network)" % bcastaddr320 print "Hint: mismatch on %s" % ' '.join([x.hostname for x in mismatches])321 return True322def _main(options):323 """mesadb 的安装脚本. 具体查看 run_install.324 """325 # 定义常量326 logger = InstallLogger()327 LOG = logger.logit328 LOG_BEGIN = logger.logit_start329 LOG_END = logger.logit_end330 LOG_RECORD = logger.record331 # 重用adminExec的功能,作为requested dba user来运行332 executor = adminExec.adminExec(makeUniquePorts = False, showNodes = False, user = options.mesadb_dba_user)333 # 执行器获得节点信息334 siteDict = executor.getNodeInfo()335 (localhost, fullhostname_list,336 addhostname_list, addhost_list,337 removehostname_list, removehost_list,338 updatehostname_list, updatehost_list ) = \339 _legacy_get_install_hosts(options, siteDict)340 downremovehosts = []341 # XXX: This needs to die a violent death.342 running_as = "root" # the user that we ssh as.343 if os.environ.get("SUDO_UID") is not None:344 running_as = os.environ.get("SUDO_USER")345 # 确定使用的ssh密码346 if options.ssh_password is not None:347 SshAuth.instance().password_used(None, running_as, options.ssh_password)348 if options.ssh_identity is not None:349 SshAuth.instance().set_identity_file(options.ssh_identity)350 # 切换状态351 switch_status(status.StatusClusterCheck(), options)352 # 设置config配置文件的install_options条目.353 cfgr = Configurator.Instance()354 cfgr.set_options( sys.argv[1:] )355 cfgr.save()356 # 收集系统的描述信息.357 factory = SystemProfileFactory.SystemProfileFactory()358 profiles = {}359 conns = {}360 unavailable_hosts = []361 ptyerrs = False362 #363 # 创建 `unavailable_hosts` 和 `conns`.364 # `conns` 只是用来创建系统描述信息的.365 #366 for h in fullhostname_list:367 c = adapterpool.DefaultAdapter(h)368 try:369 # 不需要'root'用户.370 c.connect(h, running_as)371 conns[h] = c372 except Exception as err:373 print "Warning: could not connect to %s:" % h374 print "\t%s" % str(err)375 unavailable_hosts.append( h )376 if re.search( ".*out of pty devices.*", str(err)):377 ptyerrs = True378 print "Hint: check to see whether the /dev/pts device is mounted on %s. Refer to Troubleshooting section of the documentation." % h 379 if ptyerrs:380 print "Error: Detected errors related to /dev/pts. Exiting."381 sys.exit(1)382 for uh in unavailable_hosts:383 if uh in removehostname_list:384 downremovehosts.append(uh)385 print "Ignoring down host %s because it is due to be removed." % uh386 print "Warning: %s will not have it's cluster information correctly updated" % uh387 else:388 print "Error: Cannot ignore down host %s - it is not being removed" % uh389 print "Hint: Establish connectivity to all cluster hosts before trying."390 sys.exit(1)391 try:392 profiles = factory.getProfile( conns )393 for x in conns.values():394 x.close()395 except Exception as err:396 print "Error: failed to get system information for all hosts"397 print "\t%s" % err398 print "Hint: additional failures may be hidden."399 sys.exit(1)400 # 清空描述文件,因此已经删除的主机节点就不会出现在spread config文件中了.401 for remove_host in removehostname_list:402 if remove_host in profiles:403 del profiles[remove_host]404 # 避免在相同的主机上两个主机名解析出两个不同的IP地址.405 # 描述文件在主机之间显示为相同.406 # XXX:我们已经为删除主机移除描述信息407 for (host1, prof1) in profiles.iteritems():408 for (host2, prof2) in profiles.iteritems():409 if host1 == host2:410 continue411 if prof1 == prof2:412 # 0pointer.de/blog/projects/ids.html 描述一个好的方法来标识相同主机.413 # 使用interface标识是不靠谱的.414 print "Error: It looks like %s and %s are the same host." % (host1, host2)415 print "Hint: Each cluster host must be a distinct machine."416 sys.exit(1)417 # fullhostname_list 排除我们正在移除的节点.418 for hostname in removehostname_list:419 if hostname in fullhostname_list:420 fullhostname_list.remove( hostname )421 # 如果control-subnet被指定, 保证它匹配其中一台主机.422 if options.spread_subnet is not None:423 if options.spread_subnet.lower() != 'default':424 if not spread_subnet_is_usable(options.spread_subnet, profiles):425 # the above function prints the error/hint for us.426 sys.exit(1)427 #428 # 开始安装...429 #430 # 记录进行add,remove,update等操作的主机431 LOG_RECORD("Hosts to add: %s" % addhostname_list)432 LOG_RECORD("Hosts to remove: %s" % removehostname_list)433 LOG_RECORD("Hosts to update: %s" % updatehostname_list)434 LOG_RECORD("Resulting cluster: %s" % fullhostname_list)435 installerSSH = adapterpool.AdapterConnectionPool_3.Instance()436 installerSSH.root_connect(fullhostname_list + removehostname_list, running_as)437 # 我们能够删除此检查吗?create_dba脚本创建此检查.438 # 所有的相关适配器将以 bash 脚本启动439 check_default_shell(fullhostname_list, installerSSH)440 # 管理工具不能到处运行441 try:442 Status, res = installerSSH.execute( "ps -A | grep \" python.*admin[tT]ools\$\"", hide=True )443 hostsRunning=[]444 for host in res.keys():445 if res[host][0]!="1":446 hostsRunning.append(host)447 if len(hostsRunning) > 0 :448 LOG( "There are mesadb adminTool processes running on %s. They must be stopped before installation can continue\n" % hostsRunning )449 sys.exit(1)450 except Exception, e:451 LOG( "%s" % e )452 sys.exit(1)453 # 确保没有任何不确定的权限能够运行安装进程.454 #455 # if [ -e /opt/mesadb ]; then456 # cd /tmp;457 # find /opt/mesadb -perm -755 -type d | grep '/opt/mesadb/$';458 # else459 # echo '/opt/mesadb'460 # fi461 cmd = "echo `if [ -e \""+ DBinclude.DB_DIR +"\" ]; then cd /tmp; find "+ DBinclude.DB_DIR +" -perm -755 -type d | grep \""+ DBinclude.DB_DIR +"\$\"; else echo " + DBinclude.DB_DIR + "; fi`"462 Status, res = installerSSH.execute(cmd)463 hostsRunning=[]464 for host in res.keys():465 if res[host][1][0].strip() != DBinclude.DB_DIR:466 hostsRunning.append(host)467 if len(hostsRunning) > 0 :468 LOG( "Detected invalid permissions on "+ DBinclude.DB_DIR +" directories on the following hosts: %s" % hostsRunning )469 LOG( "Permissions must be set to 755 or higher for install_mesadb to work correctly.")470 sys.exit(1)471 switch_status(status.StatusValidateSoftware(), options)472 # 在所有节点上进行初步检查.473 # 1. 检查RPM包是否OK, 是否能够正常安装474 hostsToUpgradeRPM = [] # 哪台主机需要RPM更新475 (ok, rpmBrand, rpmVersion, rpmRelease, rpmArch) = (False, None, None, None,None)476 v = profiles[localhost].mesadb477 if options.rpm_file_name is None:478 (ok, rpmBrand, rpmVersion, rpmRelease, rpmArch) = (v.isInstalled(), v.brand, v.version, v.release,v.arch)479 else:480 (ok, rpmBrand, rpmVersion, rpmRelease, rpmArch) = SSH.rpmVersion( options.rpm_file_name )481 if ok:482 if rpmBrand.lower() != "mesadb":483 LOG("RPM is not for 'mesadb'. It is for %r." % rpmBrand)484 sys.exit(1)485 if rpmVersion != v.version or rpmRelease != v.release:486 LOG("RPM must be upgraded locally, first.")487 LOG("\tLocal version = %s-%s" % (488 '.'.join([str(x) for x in v.version]),489 v.release))490 LOG("\tRPM version = %s-%s" % (491 '.'.join([str(x) for x in rpmVersion]),492 rpmRelease))493 sys.exit(1)494 # 需要知道RPM信息. 如果不知道,退出程序.495 if (not ok) or None in (rpmBrand, rpmVersion, rpmRelease, rpmArch):496 if options.rpm_file_name == None:497 LOG("No rpm file supplied and none found installed locally.")498 else:499 LOG("RPM file %s not recognized" % options.rpm_file_name)500 sys.exit(1)501 # 检查是否RPM包可用于安装502 rpm_check_fails = False503 for host in fullhostname_list:504 current = profiles[host].mesadb505 isupgradable = False506 if current.isInstalled():507 (isupgradable, iscurrentrev, msg) = current.canbeupgraded( rpmBrand, rpmVersion, rpmRelease, rpmArch )508 if not isupgradable and not iscurrentrev:509 LOG( "(%s) %s" % (host,msg) )510 sys.exit(1)511 if isupgradable or not current.isInstalled():512 hostsToUpgradeRPM.append(host)513 if len(hostsToUpgradeRPM) > 0 and options.rpm_file_name is None:514 LOG("These hosts require upgrade:")515 for host in hostsToUpgradeRPM:516 LOG("\t%s" % (host, ))517 LOG("Hosts require upgrade, but RPM (-r) not provided.")518 sys.exit(1)519 # 对于所有主机,我们需要更新RPM包, 确保 mesadb 进程没有正在运行.520 # 如果 mesadb 正在运行,RPM安装失败,则此检查将发出警告.521 if len( hostsToUpgradeRPM ) > 0:522 installerSSH.setHosts(hostsToUpgradeRPM)523 LOG_RECORD("RPM upgrade required on %s; checking for running mesadb process" % hostsToUpgradeRPM)524 try:525 # XXX: 需要处理 zombie 进程 (作为"[mesadb]"报告)526 # 在安装过程中,在 grep 中添加 regex 表达式,查找 zombies 进程527 Status, res = installerSSH.execute( "ps -A | grep ' \[\?mesadb\]\?\( <defunct>\)\?$'", hide=True )528 hostsRunningIllegally=[]529 for host in res.keys():530 if res[host][0][0]!="1":531 hostsRunningIllegally.append(host)532 if len(hostsRunningIllegally) > 0 :533 LOG( "There are mesadb processes running on %s. They must be stopped before installation can continue because an RPM upgrade is required.\n" % hostsRunningIllegally )534 sys.exit(1)535 except Exception, e:536 LOG( "%s" % e )537 sys.exit(1)538 installerSSH.resetHosts()539 switch_status(status.StatusClusterChange(), options)540 #541 # 如果 admintools.conf 文件存在,则备份此文件.542 #543 try:544 # TODO: 创建一个 SSH.backup() 命令545 Status, res = installerSSH.execute("cp %s %s.bak.%f" % (DBinclude.ADMINTOOLS_CONF, DBinclude.ADMINTOOLS_CONF, time.time()), hide=True )546 for host in res.keys():547 if res[host][0] == "0":548 LOG ("backing up admintools.conf on %s " % host)549 except Exception, e:550 LOG ("backing up admintools.conf file failed with %s \nNot a fatal error." % e)551 # 如果没有 database 定义,使用 clean 选项,然后删除 config 文件.552 # 如果没有 database 定义,用户能够更改主机名.553 c = Configurator.Instance()554 if (options.clean):555 if len(c.listDatabases()) != 0:556 LOG("Cannot perform installation with clean option as database is already defined.")557 sys.exit(1)558 # 清空所有之前的设置,启动一个新的安装进程.559 c.init_defaults()560 c.set_options( sys.argv[1:] )561 c.save()562 if not options.spread_subnet:563 options.spread_subnet = "default"564 else:565 siteDict = executor.getNodeInfo()566 definedHosts = {}567 if siteDict!={}:568 for node in siteDict.keys():569 definedHosts[siteDict[node][1]]=siteDict[node][1]570 for host in definedHosts.keys():571 # 查询主机的IP地址572 try:573 hostinfo = DBfunctions.hostname_fixup([host])[0]574 ipaddress = hostinfo[2]575 found = False576 for ip in ipaddress:577 # 更新或者删除此主机578 for cmdLineHost in updatehost_list + removehost_list:579 if ip in cmdLineHost[2]:580 found = True;581 break;582 except Exception, e:583 found = False584 if not found:585 # TODO: 查看是否用于已经申请此节点从集群中删除.586 s = "Host %s, previously defined in your cluster, is missing in -s parameter: %s"%(host, options.hosts)587 LOG(s)588 answer = "no" #ask_question(s, "yes|no", "yes")589 if answer!="yes":590 sys.exit(1)591 # RPM 文件中有一些脚本用于配置kernel, users,等.592 # 首先是在系统中获得相关软件.在每个主机上,安装 rpm 文件593 if len( hostsToUpgradeRPM ) > 0:594 switch_status(status.StatusInstallSoftware(), options)595 if DBinclude.OSNAME == "DEBIAN":596 print "Installing deb package on %s hosts...." % len( hostsToUpgradeRPM )597 else:598 print "Installing rpm on %s hosts...." % len( hostsToUpgradeRPM )599 for host in hostsToUpgradeRPM:600 # 在节点上进行 rpm 安装601 install_error = SSH.installNode( installerSSH, host, options.rpm_file_name, running_as )602 if install_error is not None:603 LOG("Install failed on %s\n%s" % (host , install_error))604 sys.exit(1)605 switch_status(status.StatusDbAdmin(), options)606 installerSSH.setHosts( fullhostname_list )607 create_dba_o= {608 'username' : options.mesadb_dba_user,609 'dbahome' : options.mesadb_dba_user_dir,610 'dbagroup' : options.mesadb_dba_group,611 'color' : sys.stdout.isatty(),612 'password-disabled' : bool(options.mesadb_dba_user_password_disabled) }613 if not empty_string(options.mesadb_dba_user_password):614 create_dba_o['password'] = options.mesadb_dba_user_password615 if not SSH.do_create_dba(installerSSH, options=create_dba_o):616 print "\nUnable to create or verify DB Admin user/group on some hosts."617 print "See above for details.\n"618 sys.exit(1)619 switch_status(status.StatusValidation(), options)620 if options.no_system_checks:621 print "Skipping system prerequisite checks (--no-system-checks)!\n"622 else:623 system_prerequisite_checks(installerSSH, localhost, options)624 switch_status(status.StatusSshKeys(), options)625 if options.no_ssh_key_install:626 print "Warning: Skipping install/repair of SSH keys for %s" % options.mesadb_dba_user627 print "Hint: You specified --no-ssh-key-install"628 print "\tHope you know what you are doing...\n"629 else:630 print "Installing/Repairing SSH keys for %s\n" % options.mesadb_dba_user631 if not SSH.installOrRepairSSHKeys(installerSSH, options.mesadb_dba_user, fullhostname_list):632 print "Error: SSH key generation or distribution failed."633 sys.exit(1)634 switch_status(status.StatusHostSetup(), options)635 installerSSH.setHosts(addhostname_list)636 print "Creating mesadb Data Directory...\n"637 res = SSH.createDataDir(installerSSH, options.mesadb_dba_user, options.data_dir)638 if not res:639 print "Warning: Could not create mesadb Data Directory. See logs"640 # FIXME: mesadb 代理使用/opt/mesadb/config/users/USERNAME/agent.conf641 # 确定什么用户来运行. 从 directory 中获取 USERNAME 值. 它需要使用admintools.conf的owner权限.642 installerSSH.execute("mkdir -p %s/%s" % (DBinclude.CONFIG_USER_DIR, options.mesadb_dba_user ), hide=True )643 installerSSH.execute("touch %s/%s/agent.conf" % (DBinclude.CONFIG_USER_DIR, options.mesadb_dba_user ), hide=True )644 # new node checking / setup.645 installerSSH.resetHosts()646 # TODO: 首先进行 netverify 和 N-way 网络测试,647 # 也可以使用options.skip_network_test来跳过测试.648 # 因此也将忽略 options\.ignore_netmask649 # 在重新配置spread之前,从admin tools siteDict中删除节点.650 # 如果正在使用此 DB 实例,drop_node 将拒绝删除此节点,651 # 同时从 spread 中拉起节点,也执行 drop_node 检查.652 # 我们并不重新配置 spread, 而是需要删除节点.653 #654 for nodeName in [node[0] for node in siteDict.values() if node[1] in removehostname_list or node[1] in downremovehosts ]:655 LOG_BEGIN("Removing node %s definition" % (nodeName))656 if not executor.drop_node( nodeName, force_if_last=True, pool=installerSSH ):657 LOG("-- couldn't remove node, it's in-use by a database!")658 sys.exit(1)659 LOG_END(True)660 # 为新主机生成节点名称661 nodeInfo = executor.getNodeInfo()662 currentnode_list = [n for n in nodeInfo.keys()]663 if options.clean:664 currentnode_list = []665 newNames = {}666 nodeCount = 1667 nodeName = "node%04d" % (nodeCount)668 for host in addhostname_list:669 # 查找未使用的节点名称670 while nodeName in currentnode_list:671 nodeCount += 1672 nodeName = "node%04d" % (nodeCount)673 newNames[nodeName] = host674 currentnode_list.append(nodeName)675 currentnode_list.sort()676 # new mechanism (Crane): installer doesn't manage spread at all677 # simply ensure spread is NOT running anywhere678 installerSSH.resetHosts()679 installerSSH.setHosts(fullhostname_list)680 # stop spread if it's running681 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh stop %s %s spread" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME))682 # remove spreadd links in /etc683 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh remove %s %s spread" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME))684 # done with spread teardown685 # 为 RPM 安装配置目录, 设置权限到DBA组686 SSH.makeDir(installerSSH, DBinclude.CONFIG_DIR, "775", options.mesadb_dba_group)687 SSH.makeDir(installerSSH, DBinclude.CONFIG_SHARE_DIR, "775", options.mesadb_dba_group)688 SSH.makeDir(installerSSH, DBinclude.CONFIG_USER_DIR, "775", options.mesadb_dba_group)689 SSH.makeDir(installerSSH, DBinclude.LOG_DIR, "775", options.mesadb_dba_group)690 SSH.makeDir(installerSSH, DBinclude.SCRIPT_DIR, "775", options.mesadb_dba_group, recursive="-R")691 installerSSH.execute("chown %s:%s %s" % ( options.mesadb_dba_user, options.mesadb_dba_group, DBinclude.CONFIG_DIR ) )692 installerSSH.execute("chown %s:%s %s" % ( options.mesadb_dba_user, options.mesadb_dba_group, DBinclude.CONFIG_SHARE_DIR ) )693 installerSSH.execute("chown %s:%s %s" % ( options.mesadb_dba_user, options.mesadb_dba_group, DBinclude.LOG_DIR ) )694 print "Updating agent..."695 # stop old agent links in /etc, if any696 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh stop %s %s %s" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME, "agent"));697 # remove old agent links in /etc, if any698 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh remove %s %s %s" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME, "agent"),699 info_msg="Removing old agent links")700 # setup agent links in /etc701 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh install %s %s %s" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME, "agent"),702 hide=True, info_msg="Setting up agent daemon")703 # start agent704 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh start %s %s %s" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME, "agent"), hide=True);705 # agent 需要一个ssl key.706 installerSSH.setHosts(fullhostname_list)707 setup_agent_key(installerSSH,708 options.mesadb_dba_user, options.mesadb_dba_group, LOG)709 # setup mesadbd links in /etc710 installerSSH.setHosts(fullhostname_list)711 Status, res = installerSSH.execute("%s/mesadb_service_setup.sh install %s %s %s" % (DBinclude.sbinDir, DBinclude.DB_DIR, DBinclude.OSNAME, "mesadb"),712 hide=True, info_msg="Setting up mesadbd autorestart")713 # 创建dba用户配置目录 /opt/mesadb/config/users/$USER714 # 当添加另外的dba用户时,我们将在所有的主机上执行此命令.715 installerSSH.setHosts(fullhostname_list)716 SSH.makeDir(installerSSH, "%s/%s"%(DBinclude.CONFIG_USER_DIR,options.mesadb_dba_user), "go-w", owner=options.mesadb_dba_user)717 # 添加新的节点到admintools结构中718 for nodeName in newNames:719 host = newNames[nodeName]720 LOG_BEGIN("Creating node %s definition for host %s" % (nodeName, host))721 executor.do_create_node( [ nodeName, host, options.data_dir, options.data_dir ],722 True, # True == Force Create723 False ) # False == Hold off on sending to cluster 724 LOG_END(True)725 # ok - 获取已经更新过的节点信息字典,发给集群726 nodedict = executor.getNodeInfo()727 c = Configurator.Instance()728 if options.direct_only:729 c.setcontrolmode("pt2pt")730 else:731 c.setcontrolmode("broadcast")732 if options.spread_subnet:733 c.setcontrolsubnet(options.spread_subnet)734 if options.spread_logging_on:735 c.setspreadlogging("True")736 else: 737 c.setspreadlogging("False")738 if options.spread_count != None:739 count = c.setlargecluster(options.spread_count)740 if count:741 print "Large cluster enabled with spread count %s" % count742 else:743 print "Large cluster disabled"744 c.save()745 switch_status(status.StatusClusterSync(), options)746 #747 # 对admintools的元数据进行最后同步, 保证拥有关系是合适的.748 #749 installerSSH.setHosts(fullhostname_list)750 executor.sendSiteInfo(nodedict, ignore_hosts=downremovehosts, pool=installerSSH)751 installerSSH.setHosts(fullhostname_list)752 # 拥有关系 (确定 dbadmin 用户)753 installerSSH.execute("chown %s:%s %s" % ( options.mesadb_dba_user,754 options.mesadb_dba_group, DBinclude.ADMINTOOLS_CONF ) )755 # 权限756 installerSSH.execute("chmod 0664 %s" % DBinclude.ADMINTOOLS_CONF )757 #758 # 同步 license759 #760 #installerSSH.setHosts(fullhostname_list)761 #eula_and_license_stuff(installerSSH, options, running_as)762 installerSSH.close()763 switch_status(status.StatusFinal(), options)764 LOG("Running upgrade logic")765 if not run_upgrades(running_as, options.mesadb_dba_user, executor):766 print "\nError: Problems upgrading your cluster. Please engage support."767 sys.exit(1)768def setup_agent_key(installerSSH, dba_user, dba_group, LOG):769 """Sets up the SSL key and certificate for the mesadb agent."""770 cfgdir = DBinclude.CONFIG_SHARE_DIR771 if os.path.exists( "/opt/mesadb/config/share/agent.key" ):772 return # nothing to do.773 # Create the SSL key locally774 if not mesadb.utils.ssl.ssl_key_gen(dba_user):775 LOG("\tError while generating SSL keys for agent communications.")776 LOG("\tSee the documentation for more details on how to update/generate")777 LOG("\ta SSL certificate for mesadb agents")778 return779 # 发送 SSL 到集群的其他节点,key around the cluster and setup permissions/ownership780 SSH.scpToPool(installerSSH, cfgdir + "/agent.key")781 SSH.scpToPool(installerSSH, cfgdir + "/agent.cert")782 SSH.scpToPool(installerSSH, cfgdir + "/agent.pem")783 installerSSH.execute("chown %s:%s %s" % ( dba_user, dba_group, cfgdir + "/agent.key" ) )784 installerSSH.execute("chown %s:%s %s" % ( dba_user, dba_group, cfgdir + "/agent.cert" ) )785 installerSSH.execute("chown %s:%s %s" % ( dba_user, dba_group, cfgdir + "/agent.pem" ) )786 installerSSH.execute("chmod 400 %s/agent.key" % cfgdir)787 installerSSH.execute("chmod 400 %s/agent.cert" % cfgdir)788 installerSSH.execute("chmod 400 %s/agent.pem" % cfgdir)789def system_prerequisite_checks(installerSSH, localhost, options):790 """Runs system prerequisite checks on the hosts defined in installerSSH"""791 thresh = options.failure_threshold792 verify_o = {793 'username' : options.mesadb_dba_user,794 'dbahome' : options.mesadb_dba_user_dir,795 'dbagroup' : options.mesadb_dba_group,796 'dry_run' : bool(options.no_system_configuration),797 'failure_threshold' : thresh }798 if not SSH.do_local_verify(installerSSH, localhost, options=verify_o):799 print "System prerequisites failed. Threshold = %s" % thresh800 print "\tHint: Fix above failures or use --failure-threshold\n"801 sys.exit(1)802 else:803 print "System prerequisites passed. Threshold = %s\n" % thresh804def eula_and_license_stuff(installerSSH, options, running_as):805 if options.accept_eula:806 fp = open(DBinclude.CONFIG_DIR +"/d5415f948449e9d4c421b568f2411140.dat","w")807 fp.write("S:a\n")808 fp.write("T:"+ str(time.time())+"\n")809 fp.write("U:"+ str( os.geteuid() ) +"\n")810 # compute the hash of the EULA file811 eula_file = open( DBinclude.binDir+"/d237f83d0a61c3594829a574c63530b.dat")812 md5hash = hashlib.md5()813 for line in eula_file.readlines():814 md5hash.update(line)815 fp.write("EULA Hash:"+md5hash.hexdigest() + "\n")816 fp.close()817 SSH.scpToPool(installerSSH, DBinclude.CONFIG_DIR + "/d5415f948449e9d4c421b568f2411140.dat")818 # always try to set the permissions on this file during install. they819 # may have been set wrong by the -Y option820 installerSSH.execute("chown %s:%s %s" % ( running_as, options.mesadb_dba_group, DBinclude.CONFIG_DIR + "/d5415f948449e9d4c421b568f2411140.dat" ) )821 installerSSH.execute("chmod 664 %s" % DBinclude.CONFIG_DIR + "/d5415f948449e9d4c421b568f2411140.dat" )822 # VER-26742823 # if no license is provided, do nothing824 # -L CE is provided, default to the CE license825 if options.license_file != None:826 license_file_to_install = options.license_file827 if license_file_to_install == "CE":828 license_file_to_install = "/opt/mesadb/config/licensing/mesadb_community_edition.license.key"829 xcc = commandLineCtrl.commandLineCtrl(False,False)830 # Install the license key (locally), printing warnings and errors if it831 # fails. Returns 0 on success. On success, copy the license key around832 if xcc.isValidLicenseKey(license_file_to_install) == 0:833 SSH.scpToPool(installerSSH, DBinclude.LICENSE_KEY)834 installerSSH.execute("chown %s:%s %s" % ( options.mesadb_dba_user, options.mesadb_dba_group, DBinclude.LICENSE_KEY) )835 # fix some old outstanding permission issues836 if os.path.exists(DBinclude.LICENSE_KEY):837 installerSSH.execute("chown %s:%s %s" % ( options.mesadb_dba_user, options.mesadb_dba_group, DBinclude.LICENSE_KEY) )838def run_install(option_parser):839 """Wraps `_main()` and returns an exit code"""840 exit_code = 0841 global g_install_status842 g_install_status = None843 try:844 switch_status(status.StatusNew(), None)845 options = option_parser()846 switch_status(status.StatusOptionValidation(), options)847 # Handles option validation and any options which quickly terminate the848 # program, such as --help and --record (does not return in those cases).849 # On error, raises an exception.850 _post_process_options(options)851 _main(options)852 except SystemExit as err:853 # The exception type raised when someone invokes sys.exit()854 exit_code = err.code855 if exit_code != 0:856 g_install_status.printFailure()857 except Exception as e:858 exit_code = 1859 g_install_status.printError(e)860 finally:861 adapterpool.AdapterConnectionPool_3.Instance().close()862 if exit_code == 0:863 g_install_status.printSuccess()864 g_install_status = None...

Full Screen

Full Screen

dv_router.py

Source:dv_router.py Github

copy

Full Screen

1"""2Your awesome Distance Vector router for CS 1683Based on skeleton code by:4 MurphyMc, zhangwen0411, lab3525"""6import sim.api as api7from cs168.dv import RoutePacket, \8 Table, TableEntry, \9 DVRouterBase, Ports, \10 FOREVER, INFINITY11class DVRouter(DVRouterBase):12 # A route should time out after this interval13 ROUTE_TTL = 1514 # Dead entries should time out after this interval15 GARBAGE_TTL = 1016 # -----------------------------------------------17 # At most one of these should ever be on at once18 SPLIT_HORIZON = False19 POISON_REVERSE = False20 # -----------------------------------------------21 22 # Determines if you send poison for expired routes23 POISON_EXPIRED = False24 # Determines if you send updates when a link comes up25 SEND_ON_LINK_UP = False26 # Determines if you send poison when a link goes down27 POISON_ON_LINK_DOWN = False28 def __init__(self):29 """30 Called when the instance is initialized.31 DO NOT remove any existing code from this method.32 However, feel free to add to it for memory purposes in the final stage!33 """34 assert not (self.SPLIT_HORIZON and self.POISON_REVERSE), \35 "Split horizon and poison reverse can't both be on"36 37 self.start_timer() # Starts signaling the timer at correct rate.38 # Contains all current ports and their latencies.39 # See the write-up for documentation.40 self.ports = Ports()41 42 # This is the table that contains all current routes43 self.table = Table()44 self.table.owner = self45 self.history = {}46 def add_static_route(self, host, port):47 """48 Adds a static route to this router's table.49 Called automatically by the framework whenever a host is connected50 to this router.51 :param host: the host.52 :param port: the port that the host is attached to.53 :returns: nothing.54 """55 # `port` should have been added to `peer_tables` by `handle_link_up`56 # when the link came up.57 assert port in self.ports.get_all_ports(), "Link should be up, but is not."58 # TODO: fill this in!59 tableEntry = TableEntry(host, port, self.ports.get_latency(port), FOREVER)60 self.table[host] = tableEntry61 def handle_data_packet(self, packet, in_port):62 """63 Called when a data packet arrives at this router.64 You may want to forward the packet, drop the packet, etc. here.65 :param packet: the packet that arrived.66 :param in_port: the port from which the packet arrived.67 :return: nothing.68 """69 # TODO: fill this in!70 dst = packet.dst71 if dst in self.table.keys():72 latency = self.table[dst][2]73 out_port = self.table[dst][1]74 if latency < INFINITY:75 self.send(packet, out_port)76 def send_routes(self, force=False, single_port=None):77 """78 Send route advertisements for all routes in the table.79 :param force: if True, advertises ALL routes in the table;80 otherwise, advertises only those routes that have81 changed since the last advertisement.82 single_port: if not None, sends updates only to that port; to83 be used in conjunction with handle_link_up.84 :return: nothing.85 """86 # TODO: fill this in!87 for host, tableEntry in self.table.items():88 port = tableEntry[1]89 if single_port is None:90 for out_port in self.ports.get_all_ports():91 if self.SPLIT_HORIZON:92 if out_port != port:93 latency = tableEntry[2]94 routePacket = RoutePacket(host, latency)95 if not force:96 if (out_port,host) not in self.history.keys() or self.history[(out_port,host)].latency != routePacket.latency:97 self.send(routePacket, out_port)98 self.history[(out_port,host)] = routePacket99 else:100 self.send(routePacket, out_port)101 self.history[(out_port, host)] = routePacket102 elif self.POISON_REVERSE:103 if out_port != port:104 latency = tableEntry[2]105 else:106 latency = INFINITY107 routePacket = RoutePacket(host, latency)108 if not force:109 if (out_port, host) not in self.history.keys() or self.history[(out_port,host)].latency != routePacket.latency:110 self.send(routePacket, out_port)111 self.history[(out_port, host)] = routePacket112 else:113 self.send(routePacket, out_port)114 self.history[(out_port, host)] = routePacket115 else:116 latency = tableEntry[2]117 routePacket = RoutePacket(host, latency)118 if not force:119 if (out_port, host) not in self.history.keys() or self.history[(out_port,host)].latency != routePacket.latency:120 self.send(routePacket, out_port)121 self.history[(out_port, host)] = routePacket122 else:123 self.send(routePacket, out_port)124 self.history[(out_port, host)] = routePacket125 else:126 out_port = single_port127 if self.SPLIT_HORIZON:128 if out_port != port:129 latency = tableEntry[2]130 routePacket = RoutePacket(host, latency)131 if not force:132 if (out_port,host) not in self.history.keys() or self.history[(out_port,host)].latency != routePacket.latency:133 self.send(routePacket, out_port)134 self.history[(out_port,host)] = routePacket135 else:136 self.send(routePacket, out_port)137 self.history[(out_port, host)] = routePacket138 elif self.POISON_REVERSE:139 if out_port != port:140 latency = tableEntry[2]141 else:142 latency = INFINITY143 routePacket = RoutePacket(host, latency)144 if not force:145 if (out_port, host) not in self.history.keys() or self.history[(out_port,host)].latency != routePacket.latency:146 self.send(routePacket, out_port)147 self.history[(out_port, host)] = routePacket148 else:149 self.send(routePacket, out_port)150 self.history[(out_port, host)] = routePacket151 else:152 latency = tableEntry[2]153 routePacket = RoutePacket(host, latency)154 if not force:155 if (out_port, host) not in self.history.keys() or self.history[(out_port,host)].latency != routePacket.latency:156 self.send(routePacket, out_port)157 self.history[(out_port, host)] = routePacket158 else:159 self.send(routePacket, out_port)160 self.history[(out_port, host)] = routePacket161 def expire_routes(self):162 """163 Clears out expired routes from table.164 accordingly.165 """166 # TODO: fill this in!167 remove_hosts = []168 for host, tableEntry in self.table.items():169 expire_time = tableEntry[3]170 if(api.current_time() > expire_time):171 remove_hosts.append(host)172 if self.POISON_EXPIRED:173 for remove_host in remove_hosts:174 port = self.table[remove_host][1]175 self.table.pop(remove_host)176 tableEntry = TableEntry(remove_host, port, INFINITY, FOREVER)177 self.table[remove_host] = tableEntry178 else:179 for remove_host in remove_hosts:180 self.table.pop(remove_host)181 def handle_route_advertisement(self, route_dst, route_latency, port):182 """183 Called when the router receives a route advertisement from a neighbor.184 :param route_dst: the destination of the advertised route.185 :param route_latency: latency from the neighbor to the destination.186 :param port: the port that the advertisement arrived on.187 :return: nothing.188 """189 # TODO: fill this in!190 is_poisoned = (route_latency == INFINITY)191 if is_poisoned:192 new_latency = INFINITY193 else:194 new_latency = route_latency + self.ports.get_latency(port)195 if route_dst not in self.table.keys():196 if not is_poisoned:197 self.table[route_dst] = TableEntry(route_dst, port, new_latency, api.current_time() + self.ROUTE_TTL)198 self.send_routes()199 else:200 current_latency = self.table[route_dst][2]201 current_port = self.table[route_dst][1]202 if new_latency < current_latency or port == current_port:203 if is_poisoned:204 self.table[route_dst] = TableEntry(route_dst, port, new_latency,api.current_time())205 self.send_routes()206 else:207 self.table[route_dst] = TableEntry(route_dst, port, new_latency, api.current_time() + self.ROUTE_TTL)208 self.send_routes()209 def handle_link_up(self, port, latency):210 """211 Called by the framework when a link attached to this router goes up.212 :param port: the port that the link is attached to.213 :param latency: the link latency.214 :returns: nothing.215 """216 self.ports.add_port(port, latency)217 # TODO: fill in the rest!218 if self.SEND_ON_LINK_UP:219 self.send_routes(False, port)220 def handle_link_down(self, port):221 """222 Called by the framework when a link attached to this router does down.223 :param port: the port number used by the link.224 :returns: nothing.225 """226 self.ports.remove_port(port)227 # TODO: fill this in!228 if(self.POISON_ON_LINK_DOWN):229 remove_hosts = []230 for host, tableEntry in self.table.items():231 if port == tableEntry[1]:232 remove_hosts.append(host)233 for remove_host in remove_hosts:234 port = self.table[remove_host][1]235 self.table.pop(remove_host)236 tableEntry = TableEntry(remove_host, port, INFINITY, FOREVER)237 self.table[remove_host] = tableEntry238 self.send_routes()...

Full Screen

Full Screen

rmyhosts.py

Source:rmyhosts.py Github

copy

Full Screen

2home = os.path.expanduser("~")3parser = argparse.ArgumentParser(description='This script removes hosts from saved ssh known_hosts file')4parser.add_argument("--hosts", nargs="*", help="Enter list of hosts to remove. Ex: rmyhosts --hosts 192.168.1.2 192.168.1.3 192.168.1.4", required=True)5args = parser.parse_args()6def remove_hosts():7 try:8 if not os.path.exists("{}/.ssh/known_hosts".format(home)):9 raise Exception("Cannot locate: {}/.ssh/known_hosts".format(home))10 else:11 if len(args.hosts) >= 1:12 # read known hosts file13 f = open("{}/.ssh/known_hosts".format(home), "r")14 known_hosts = f.readlines()15 f.close()16 # iterate and remove given ips from the args list17 for host in args.hosts:18 for line in known_hosts:19 if host == line.split(" ")[0]:20 known_hosts.remove(line)21 # rewrite known_hosts file22 f = open("{}/.ssh/known_hosts".format(home), "w")23 f.write("".join(known_hosts))24 f.close()25 print("{}: have been removed from the hosts file".format(args.hosts))26 else:27 raise Exception("You must pass at least one ip address in command line arguments")28 except Exception as err:29 print(err)30if __name__ == "__main__":...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run autotest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful