Collection of GNS3 GUI Tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.6 KiB

  1. #!/usr/local/bin/python3
  2. """
  3. start_nodes - start nodes of a project one by one
  4. """
  5. import os
  6. import sys
  7. import time
  8. import gns3api
  9. def start_node_list(api, node_list):
  10. """ start nodes, yield sleeps the specified number of seconds """
  11. delay_next_node = 0
  12. for node in node_list:
  13. if delay_next_node > 0: # delay between starting nodes
  14. yield delay_next_node
  15. while True:
  16. compute = api.request('GET', ('/v2/computes', node['compute_id']))
  17. if compute['cpu_usage_percent'] < 60.0:
  18. break
  19. yield 4 # test again in 4 seconds
  20. print("Starting '{}'".format(node['name']))
  21. api.request("POST", ("/v2/projects", node['project_id'],
  22. 'nodes', node['node_id'], 'start'))
  23. if node['node_type'] in ("qemu", "virtualbox", "vmware"):
  24. delay_next_node = 4
  25. else:
  26. delay_next_node = 2
  27. def start_nodes(argv):
  28. """ parse command line, retrieve nodes and start nodes one by one """
  29. # get arguments
  30. if len(argv) < 4:
  31. sys.exit("usage:\nstart_nodes version parameter-file project-id [sel-item ...]")
  32. try:
  33. with open(argv[2], "r") as file:
  34. cntl_url, cntl_user, cntl_passwd, *_ = file.read(512).splitlines()
  35. if argv[2].endswith(".tmp"):
  36. os.remove(argv[2])
  37. except (OSError, ValueError) as err:
  38. sys.exit("Can't get controller connection params: {}".format(err))
  39. project_id = argv[3]
  40. sel_items = argv[4:]
  41. # connect to GNS3 controller
  42. try:
  43. api = gns3api.GNS3Api(cntl_url, cntl_user, cntl_passwd)
  44. except gns3api.GNS3ApiException as err:
  45. sys.exit("Can't connect to GNS3 controller: {}".format(err))
  46. # get node information
  47. nodes = {}
  48. try:
  49. for node in api.request('GET', ('/v2/projects', project_id, 'nodes')):
  50. nodes[node['node_id']] = node
  51. except gns3api.GNS3ApiException as err:
  52. sys.exit("Can't get node information: {}".format(err))
  53. if not nodes:
  54. sys.exit("No node in project")
  55. # get selected nodes
  56. if not sel_items:
  57. sel_nodes = list(nodes.keys())
  58. else:
  59. sel_nodes = [item[6:] for item in sel_items
  60. if item.startswith("nodes/")]
  61. if not sel_nodes:
  62. sys.exit("No node selected")
  63. sel_nodes.sort(key=lambda k: nodes[k]['name'].lower())
  64. # create nodes list per compute
  65. compute_nodes = {}
  66. for node_id in sel_nodes:
  67. node = nodes[node_id]
  68. if node['status'] != 'started':
  69. compute_nodes.setdefault(node['compute_id'], []).append(node)
  70. # iterate through compute_nodes and start them
  71. print("Starting nodes one by one")
  72. tasks = {compute_id: {
  73. 'iter': start_node_list(api, compute_nodes[compute_id]),
  74. 'delay': 0}
  75. for compute_id in compute_nodes}
  76. while tasks:
  77. delay = min([tasks[compute_id]['delay'] for compute_id in tasks])
  78. if delay > 0.09:
  79. time.sleep(delay)
  80. for compute_id in list(tasks.keys()):
  81. tasks[compute_id]['delay'] -= delay
  82. if tasks[compute_id]['delay'] <= 0.09:
  83. try:
  84. tasks[compute_id]['delay'] = \
  85. max(0, next(tasks[compute_id]['iter']))
  86. except StopIteration:
  87. del tasks[compute_id]
  88. except gns3api.GNS3ApiException as err:
  89. sys.exit("Can't start node: {}".format(err))
  90. try:
  91. start_nodes(sys.argv)
  92. except KeyboardInterrupt:
  93. print()
  94. sys.exit("Aborted\n")