def CMDbots(parser, args): """Returns information about the bots connected to the Swarming server.""" add_filter_options(parser) parser.filter_group.add_option( "--dead-only", action="store_true", help="Only print dead bots, useful to reap them and reimage broken bots" ) parser.filter_group.add_option("-k", "--keep-dead", action="store_true", help="Do not filter out dead bots") parser.filter_group.add_option("-b", "--bare", action="store_true", help="Do not print out dimensions") options, args = parser.parse_args(args) if options.keep_dead and options.dead_only: parser.error("Use only one of --keep-dead and --dead-only") bots = [] cursor = None limit = 250 # Iterate via cursors. base_url = options.swarming + "/_ah/api/swarming/v1/bots/list?limit=%d" % limit while True: url = base_url if cursor: url += "&cursor=%s" % urllib.quote(cursor) data = net.url_read_json(url) if data is None: print >> sys.stderr, "Failed to access %s" % options.swarming return 1 bots.extend(data["items"]) cursor = data.get("cursor") if not cursor: break for bot in natsort.natsorted(bots, key=lambda x: x["bot_id"]): if options.dead_only: if not bot.get("is_dead"): continue elif not options.keep_dead and bot.get("is_dead"): continue # If the user requested to filter on dimensions, ensure the bot has all the # dimensions requested. dimensions = {i["key"]: i["value"] for i in bot["dimensions"]} for key, value in options.dimensions: if key not in dimensions: break # A bot can have multiple value for a key, for example, # {'os': ['Windows', 'Windows-6.1']}, so that --dimension os=Windows will # be accepted. if isinstance(dimensions[key], list): if value not in dimensions[key]: break else: if value != dimensions[key]: break else: print bot["bot_id"] if not options.bare: print " %s" % json.dumps(dimensions, sort_keys=True) if bot.get("task_id"): print " task: %s" % bot["task_id"] return 0
def CMDquery(parser, args): """Returns information about the bots connected to the Swarming server.""" add_filter_options(parser) parser.filter_group.add_option( '--dead-only', action='store_true', help='Only print dead bots, useful to reap them and reimage broken bots' ) parser.filter_group.add_option('-k', '--keep-dead', action='store_true', help='Do not filter out dead bots') parser.filter_group.add_option('-b', '--bare', action='store_true', help='Do not print out dimensions') options, args = parser.parse_args(args) if options.keep_dead and options.dead_only: parser.error('Use only one of --keep-dead and --dead-only') service = net.get_http_service(options.swarming) data = service.json_request('GET', '/swarming/api/v1/bots') if data is None: print >> sys.stderr, 'Failed to access %s' % options.swarming return 1 timeout = datetime.timedelta(seconds=data['machine_death_timeout']) utcnow = datetime.datetime.utcnow() for machine in natsort.natsorted(data['machines'], key=lambda x: x['id']): last_seen = datetime.datetime.strptime(machine['last_seen'], '%Y-%m-%d %H:%M:%S') is_dead = utcnow - last_seen > timeout if options.dead_only: if not is_dead: continue elif not options.keep_dead and is_dead: continue # If the user requested to filter on dimensions, ensure the bot has all the # dimensions requested. dimensions = machine['dimensions'] for key, value in options.dimensions: if key not in dimensions: break # A bot can have multiple value for a key, for example, # {'os': ['Windows', 'Windows-6.1']}, so that --dimension os=Windows will # be accepted. if isinstance(dimensions[key], list): if value not in dimensions[key]: break else: if value != dimensions[key]: break else: print machine['id'] if not options.bare: print ' %s' % dimensions return 0
def CMDquery(parser, args): """Returns information about the bots connected to the Swarming server.""" add_filter_options(parser) parser.filter_group.add_option( '--dead-only', action='store_true', help='Only print dead bots, useful to reap them and reimage broken bots') parser.filter_group.add_option( '-k', '--keep-dead', action='store_true', help='Do not filter out dead bots') parser.filter_group.add_option( '-b', '--bare', action='store_true', help='Do not print out dimensions') options, args = parser.parse_args(args) if options.keep_dead and options.dead_only: parser.error('Use only one of --keep-dead and --dead-only') auth.ensure_logged_in(options.swarming) service = net.get_http_service(options.swarming) data = service.json_request('GET', '/swarming/api/v1/bots') if data is None: print >> sys.stderr, 'Failed to access %s' % options.swarming return 1 for machine in natsort.natsorted(data['machines'], key=lambda x: x['id']): if options.dead_only: if not machine['is_dead']: continue elif not options.keep_dead and machine['is_dead']: continue # If the user requested to filter on dimensions, ensure the bot has all the # dimensions requested. dimensions = machine['dimensions'] for key, value in options.dimensions: if key not in dimensions: break # A bot can have multiple value for a key, for example, # {'os': ['Windows', 'Windows-6.1']}, so that --dimension os=Windows will # be accepted. if isinstance(dimensions[key], list): if value not in dimensions[key]: break else: if value != dimensions[key]: break else: print machine['id'] if not options.bare: print ' %s' % dimensions return 0
def CMDquery(parser, args): """Returns information about the bots connected to the Swarming server.""" add_filter_options(parser) parser.filter_group.add_option( "--dead-only", action="store_true", help="Only print dead bots, useful to reap them and reimage broken bots" ) parser.filter_group.add_option("-k", "--keep-dead", action="store_true", help="Do not filter out dead bots") parser.filter_group.add_option("-b", "--bare", action="store_true", help="Do not print out dimensions") options, args = parser.parse_args(args) if options.keep_dead and options.dead_only: parser.error("Use only one of --keep-dead and --dead-only") service = net.get_http_service(options.swarming) data = service.json_request("GET", "/swarming/api/v1/bots") if data is None: print >> sys.stderr, "Failed to access %s" % options.swarming return 1 timeout = datetime.timedelta(seconds=data["machine_death_timeout"]) utcnow = datetime.datetime.utcnow() for machine in natsort.natsorted(data["machines"], key=lambda x: x["tag"]): last_seen = datetime.datetime.strptime(machine["last_seen"], "%Y-%m-%d %H:%M:%S") is_dead = utcnow - last_seen > timeout if options.dead_only: if not is_dead: continue elif not options.keep_dead and is_dead: continue # If the user requested to filter on dimensions, ensure the bot has all the # dimensions requested. dimensions = machine["dimensions"] for key, value in options.dimensions: if key not in dimensions: break # A bot can have multiple value for a key, for example, # {'os': ['Windows', 'Windows-6.1']}, so that --dimension os=Windows will # be accepted. if isinstance(dimensions[key], list): if value not in dimensions[key]: break else: if value != dimensions[key]: break else: print machine["tag"] if not options.bare: print " %s" % dimensions return 0
def get_bot_list(swarming_server, dimensions): """Returns a list of swarming bots: health, quarantined, dead.""" q = '&'.join( 'dimensions=%s:%s' % (k, v) for k, v in sorted(dimensions.iteritems())) cmd = [ sys.executable, 'swarming.py', 'query', '--swarming', swarming_server, '--limit', '0', 'bots/list?' + q, ] healthy = [] quarantined = [] dead = [] results = json.loads(subprocess.check_output(cmd, cwd=ROOT_DIR)) if not results.get('items'): return (), (), () for b in results['items']: if b['is_dead']: dead.append(b['bot_id']) elif b['quarantined']: quarantined.append(b['bot_id']) else: healthy.append(b['bot_id']) return natsort.natsorted(healthy), quarantined, dead
def CMDbots(parser, args): """Returns information about the bots connected to the Swarming server.""" add_filter_options(parser) parser.filter_group.add_option( '--dead-only', action='store_true', help='Only print dead bots, useful to reap them and reimage broken bots') parser.filter_group.add_option( '-k', '--keep-dead', action='store_true', help='Do not filter out dead bots') parser.filter_group.add_option( '-b', '--bare', action='store_true', help='Do not print out dimensions') options, args = parser.parse_args(args) if options.keep_dead and options.dead_only: parser.error('Use only one of --keep-dead and --dead-only') bots = [] cursor = None limit = 250 # Iterate via cursors. base_url = ( options.swarming + '/_ah/api/swarming/v1/bots/list?limit=%d' % limit) while True: url = base_url if cursor: url += '&cursor=%s' % urllib.quote(cursor) data = net.url_read_json(url) if data is None: print >> sys.stderr, 'Failed to access %s' % options.swarming return 1 bots.extend(data['items']) cursor = data.get('cursor') if not cursor: break for bot in natsort.natsorted(bots, key=lambda x: x['bot_id']): if options.dead_only: if not bot.get('is_dead'): continue elif not options.keep_dead and bot.get('is_dead'): continue # If the user requested to filter on dimensions, ensure the bot has all the # dimensions requested. dimensions = {i['key']: i.get('value') for i in bot['dimensions']} for key, value in options.dimensions: if key not in dimensions: break # A bot can have multiple value for a key, for example, # {'os': ['Windows', 'Windows-6.1']}, so that --dimension os=Windows will # be accepted. if isinstance(dimensions[key], list): if value not in dimensions[key]: break else: if value != dimensions[key]: break else: print bot['bot_id'] if not options.bare: print ' %s' % json.dumps(dimensions, sort_keys=True) if bot.get('task_id'): print ' task: %s' % bot['task_id'] return 0