Exemplo n.º 1
0
 def __init__(self, zk, path, hostname, hostid):
     try:
         zk.get_children(path)
     except kazoo.exceptions.NoNodeError:
         raise RuntimeError("role lock node '%s' must exist" % path)
     self.zk = zk
     self.path = path
     self.hostname = hostname
     self.hostid = hostid
Exemplo n.º 2
0
def main(args=None):
    if args is None:
        args = sys.argv[1:]

    zkconnection_string, path, host = args

    zk = zc.zk.ZK(zkconnection_string)
    addrs = [addr for addr in zk.get_children(path)
             if addr.startswith(host+':')]
    if not addrs:
        return error("Server not registered")

    if len(addrs) > 1:
        return error("Too many servers registered")

    addr = addrs[0]
    url = 'http://%s/ruok' % addr
    try:
        r = requests.get(url)
    except requests.ConnectionError:
        return error("Can't connect to %r" % addr)

    if r.status_code != 200 or r.text != "imok":
        return error("bad response from %r" % url)

    print "cool"
Exemplo n.º 3
0
def sync_with_canonical(url, dry_run=False, force=False, tree_directory=None):
    zk = zc.zk.ZK(ZK_LOCATION)
    zk_version = get_zk_version(zk)
    if zk_version is None:
        logger.critical("ALL STOP, cluster version is None")
        if not force:
            return

    retries = 0
    while True:
        try:
            if url.startswith('svn') or url.startswith('file://'):
                vcs = SVN(url)
            else:
                vcs = GIT(url, tree_directory)
            break
        except RuntimeError:
            retries += 1
            if retries > MAX_VCS_RETRIES:
                raise
            time.sleep(3)

    logger.info("VCS Version: " + str(vcs.version))
    logger.info("ZK Version: " + str(zk_version))
    if zk_version != vcs.version:
        if not (force or zk_version is False):
            for child in zk.get_children('/hosts'):
                host_version = zk.properties('/hosts/' + child)['version']
                if host_version != zk_version:
                    logger.error(
                        "Version mismatch detected, can't resync since " +
                        "host %s has not converged (%s -> %s)" %
                        (child, host_version, zk_version))
                    return

        cluster_lock = zk.client.Lock('/hosts-lock', str(os.getpid()))
        if cluster_lock.acquire(0):
            try:
                logger.info("Version mismatch detected, resyncing")

                # Import changes
                for fi, contents in vcs:
                    output = ' '.join(('Importing', fi))
                    if dry_run:
                        output += ' (dry run, no action taken)'
                    logger.info(output)
                    if not dry_run:
                        zk.import_tree(contents, trim=fi.endswith('.zk'))
                # bump version number
                if not dry_run:
                    zk.properties('/hosts').update(version=vcs.version)
            finally:
                cluster_lock.release()
        else:
            logger.error("Refused to update zookeeper tree, "
                         "couldn't obtain cluster lock")

    zk.close()
Exemplo n.º 4
0
    def process(self, cb):
        try:
            zk = self.zk
        except AttributeError:
            try:
                self.zk = zc.zk.ZK('zookeeper:2181')
            except zookeeper.ZooKeeperException:
                return self.error(cb, self.url, "Can't connect to ZooKeeper")
            zk = self.zk

        try:
            hosts = zk.get_properties('/hosts')
        except zookeeper.NoNodeException:
            return self.error(cb, self.url, "No node: /hosts")

        if 'version' not in hosts:
            return self.error(cb, self.url, "No version: /hosts")

        now = time.time()
        version = hosts['version']
        if version != getattr(self, 'version', self):
            self.version = version
            self.version_time = now
            self.version_times = {}

        times = self.version_times
        late = []

        for name in zk.get_children('/hosts'):
            properties = zk.get_properties('/hosts/'+name)
            if 'version' in properties:
                name = properties.get('name', name)
                if properties['version'] == version:
                    if name in times:
                        del times[name]
                        if not times:
                            self.version_time = now
                    continue
                if name in times:
                    dur = int(now - times[name]) / 60
                else:
                    times[name] = now
                    dur = 0
                late.append((dur, name))

        if late:
            late.sort()
            dur, name = late[-1]
            mess = 'Unconverged (%s after %s minutes)' % (name, dur)
            if dur > 30:
                self.error(cb, self.url, mess)
            elif dur > 15:
                self.warn(cb, self.url, mess)
            else:
                self.ok(cb, self.url, mess)
        else:
            self.ok(cb, self.url, 'Converged (%s since %s)' % (
                version, time.ctime(self.version_time)))
Exemplo n.º 5
0
def find_server(zookeeper, path, monitor_address):
    server = None
    if monitor_address:
        try:
            fp, s = connect(monitor_address)
        except socket.error as err:
            return print("Can't connect %s" % err)

        s.settimeout(1.0)
        fp.write('servers %s\n' % path)
        fp.flush()
        data = fp.read().strip()
        fp.close(); s.close()
        if data.lower().startswith("invalid "):
            return print(data + ' at %r' % monitor_address)
        servers = list(set(data.split())) # dedup
        if not servers:
            return print("No servers at: %r" % monitor_address)
        if len(servers) > 1:
            return print("Too many servers, %r, at: %r" %
                         (sorted(servers), monitor_address))
        server = servers[0]

    zk = zc.zk.ZK(zookeeper)
    children = zk.get_children(path)
    zk.close()
    if server:
        host, port = server.split(':')
        if host:
            children = [c for c in children if c == server]
        else:
            children = [c for c in children if c.split(':')[1] == port]

    if len(children) != 1:
        return print("Couldn't find server in ZooKeeper")
    addr = children[0]
    return addr
Exemplo n.º 6
0
def my_func(event):
    # check to see what the children are now
    path = event.path
    addresses = zk.get_children(event.path)
    create_cgf(path,addresses)
Exemplo n.º 7
0
        temp = "/%s-%s-%s-%s" % (datacenter,server_type,location,environment)
        zookeeper_path_list.append(temp)
    return service_hash, zookeeper_path_list

def get_ip_encode(children):
    ip_encode = ''.join(list(children))
    ip_encode = base64.b64encode(ip_encode)
    return ip_encode
 
while True:
    service_hash, zookeeper_path_list = get_service_hash()
    for path in zookeeper_path_list:
        try:
            exists = zk.exists(path)
        except KazooException:
            exists = None
            zk = get_zk_conn()
        if exists:
            children = zk.get_children(path, watch=my_func)
            print path,children
            
            ip_encode = get_ip_encode(children)
            server_type = path.split('-')[1]
            if os.path.isfile('/etc/haproxy/conf.d/%s-%s.cfg' % (server_type,ip_encode))==False:
                create_cgf(path,list(children))
                
            
    sys.stdout.flush()
    sys.stderr.flush()
    time.sleep(.5)
Exemplo n.º 8
0
def my_func(event):
    # check to see what the children are now
    path = event.path
    addresses = zk.get_children(event.path)
    create_cgf(path, addresses)
Exemplo n.º 9
0
    return service_hash, zookeeper_path_list


def get_ip_encode(children):
    ip_encode = ''.join(list(children))
    ip_encode = base64.b64encode(ip_encode)
    return ip_encode


while True:
    service_hash, zookeeper_path_list = get_service_hash()
    for path in zookeeper_path_list:
        try:
            exists = zk.exists(path)
        except KazooException:
            exists = None
            zk = get_zk_conn()
        if exists:
            children = zk.get_children(path, watch=my_func)
            print path, children

            ip_encode = get_ip_encode(children)
            server_type = path.split('-')[1]
            if os.path.isfile('/etc/haproxy/conf.d/%s-%s.cfg' %
                              (server_type, ip_encode)) == False:
                create_cgf(path, list(children))

    sys.stdout.flush()
    sys.stderr.flush()
    time.sleep(.5)
Exemplo n.º 10
0
def clients(path):
    logging.basicConfig()
    random.seed(0)

    import zc.zk
    zk = zc.zk.ZooKeeper()

    properties = zk.properties(path)
    settings = zc.mappingobject.mappingobject(properties)

    siteids = []

    @properties
    def _(*a):
        n = settings.sites
        siteids[:] = [0]
        for i in range(4):
            if n:
                siteids.extend(range(n))
            n /= 2

    wpath = path + '/lb/providers'
    zope.testing.wait.wait(lambda : zk.get_children(wpath))

    [waddr] = zk.get_children(wpath)
    waddr = zc.parse_addr.parse_addr(waddr)

    stats = zc.mappingobject.mappingobject(dict(
        truncated = 0,
        requests = 0,
        bypid = {},
        nobs = 0,
        nhits = 0,
        ))

    spath = path + '/stats'
    if not zk.exists(spath):
        zk.create(spath, '', zc.zk.OPEN_ACL_UNSAFE)

    import gevent.socket

    def do_request():
        siteid = random.choice(siteids)
        oids = set(
            int(random.gauss(0, settings.objects_per_site/4))
            for i in range(settings.objects_per_request)
            )
        socket = gevent.socket.create_connection(waddr)
        try:
            socket.sendall(
                request_template % dict(
                    data='_'.join(map(str, oids)),
                    host='h%s' % siteid,
                    )
                )
            response = ''
            while '\r\n\r\n' not in response:
                data = socket.recv(9999)
                if not data:
                    stats.truncated += 1
                    return
                response += data
            headers, body = response.split('\r\n\r\n')
            headers = headers.split('\r\n')
            status = headers.pop(0)
            headers = dict(l.strip().lower().split(':', 1)
                           for l in headers if ':' in l)
            content_length = int(headers['content-length'])
            while len(body) < content_length:
                data = socket.recv(9999)
                if not data:
                    stats.truncated += 1
                    return
                body += data

            pid, n, nhit, nmiss, nevict = map(int, body.strip().split())
            stats.requests += 1
            stats.nobs += n
            stats.nhits += nhit
            bypid = stats.bypid.get(pid)
            if bypid is None:
                bypid = stats.bypid[pid] = dict(nr=0, n=0, nhit=0)
            bypid['nr'] += 1
            bypid['n'] += n
            bypid['nhit'] += nhit
            logger.info(' '.join(map(str, (
                100*stats.nhits/stats.nobs,
                pid, n, nhit, 100*nhit/n,
                ))))
        finally:
            socket.close()

    def client():
        try:
            while 1:
                do_request()
        except:
            print 'client error'
            logging.getLogger(__name__+'-client').exception('client')

    greenlets = [gevent.spawn(client) for i in range(settings.clients)]


    # Set up notification of address changes.
    watcher = gevent.get_hub().loop.async()
    @watcher.start
    def _():
        print 'got update event'
        while settings.clients > len(greenlets):
            greenlets.append(gevent.spawn(client))
        while settings.clients < len(greenlets):
            greenlets.pop().kill()

    properties(lambda a: watcher.send())

    while 1:
        gevent.sleep(60.0)