def get_cluster_status(): try: return requests.get("{}admin/collections?action=CLUSTERSTATUS".format( SDAP_SOLR_URL)).json() except (requests.exceptions.ConnectionError, json.decoder.JSONDecodeError): return False logging.info("Attempting to aquire lock from {}".format(SDAP_ZK_SOLR)) zk_host, zk_chroot = SDAP_ZK_SOLR.split('/') zk = KazooClient(hosts=zk_host) zk.start() zk.ensure_path(zk_chroot) zk.chroot = zk_chroot lock = zk.Lock("/collection-creator", ZK_LOCK_GUID) try: with lock: # blocks waiting for lock acquisition logging.info( "Lock aquired. Checking for SolrCloud at {}".format(SDAP_SOLR_URL)) # Wait for MAX_RETRIES for the entire Solr cluster to be available. attempts = 0 status = None collection_exists = False while attempts <= MAX_RETRIES: status = get_cluster_status() if not status: # If we can't get the cluster status, my Solr node is not running attempts += 1 logging.info("Waiting for Solr at {}".format(SDAP_SOLR_URL))
def main(): parser = argparse.ArgumentParser(description=( "Distributed locking using Zookeeper primarily for scripting. " "After acquiring the lock, the zk node is printed to STDOUT. This " "zk node should be passed to unlock. Note: all logs are printed to STDERR" )) parser.add_argument("-s", "--servers", default='127.0.0.1:2181') parser.add_argument("-c", "--chroot", default='/devops', type=lambda d: d.rstrip('/'), help="ZK chroot for the lock path") parser.add_argument( "-i", "--identifier", default=None, help="Optional string identifier to add to the lock node " "OR verify when unlocking") parser.add_argument( "action", choices=["lock", "rlock", "wlock", "unlock", "list"], help=("lock: acquire a mutex lock. rlock: acquire a read lock " "wlock: acquire a write lock. unlock: release lock " "identified by zk node. list: list all lock contenders")) parser.add_argument( "lock_path", type=lambda d: d.rstrip('/'), help= ("ZK path to lock OR ZK node to unlock. For the unlock" "action this must be the chrooted zk path to the node e.g." "lockpick lock -c /devops /mylock" "lockpick unlock -c /devops /mylock/9d2badeec7684f35b10f4860db42e45c__rlock__0000000022" )) parser.add_argument('-v', '--verbose', default=0, action='count') parser.add_argument('-r', '--retry-count', default=3, type=int) parser.add_argument('-p', '--retry-sleep', default=3, type=int) args = parser.parse_args() logger.setLevel(log_level(args.verbose)) zk = KazooClient(hosts=args.servers) zk.chroot = args.chroot zk.start() if args.action == 'unlock': result = release_lock(zk, args.lock_path, args.identifier) zk.stop() if not result: return 1 elif args.action == 'list': for contender in list_contenders(zk, args.lock_path): print contender else: l = acquire_lock(zk, args.action, args.lock_path, args.identifier, args.retry_count, args.retry_sleep) if l and l.is_acquired: zk_path = args.lock_path + '/' + l.node logger.info("Lock {0} with path {1} acquired".format( args.lock_path, zk_path)) print zk_path else: logger.error("Failed to acquire lock within timeout!") zk.stop() return 1 zk.stop() return 0