예제 #1
0
파일: master.py 프로젝트: ceache/treadmill
    def configure(server, features, parent, partition, memory, cpu, disk):
        """Create, get or modify server configuration"""
        if parent:
            path = parent.split('/')
            bucket = None
            for bucket, bucket_parent in zip(path, [None] + path[:-1]):
                masterapi.create_bucket(context.GLOBAL.zk.conn, bucket,
                                        bucket_parent)
            assert bucket is not None, 'server topology missing.'

            masterapi.create_server(context.GLOBAL.zk.conn,
                                    server,
                                    bucket,
                                    partition=partition)

        features = cli.combine(features)
        if features:
            # This is special case - reset features to empty.
            if features == ['-']:
                features = []

            masterapi.update_server_features(context.GLOBAL.zk.conn, server,
                                             features)

        if memory or cpu or disk:
            masterapi.update_server_capacity(context.GLOBAL.zk.conn,
                                             server,
                                             memory=memory,
                                             cpu=cpu,
                                             disk=disk)

        server_obj = masterapi.get_server(context.GLOBAL.zk.conn, server)
        server_obj['name'] = server

        cli.out(formatter(server_obj))
예제 #2
0
def sync_server_topology():
    """Sync servers into buckets in the masterapi.
    """
    admin_srv = admin.Server(context.GLOBAL.ldap.conn)
    servers = admin_srv.list({'cell': context.GLOBAL.cell})
    zkclient = context.GLOBAL.zk.conn

    # Cells are composed of buckets. The topology is ~1000 servers per pod
    # with each pod composed of racks, each ~40 servers.
    def _server_pod_rack(servername):
        # In the absence of any information about the server and topology, we
        # simply hash the servername and use the value to place the server in
        # a fictive topology of at most 4 pods, each with 16 racks.
        svr_hash = hashlib.md5(servername.encode()).hexdigest()
        svr_id = int(svr_hash, 16)  # That is a 128 bit number
        pod = (svr_id >> (128 - 2))  # First 2 bits -> pod
        # below the first 2 bits, we take the rest, modulo 16
        rack = (svr_id % (1 << (128 - 2))) % 16
        return (pod, rack)

    for server in servers:
        servername = server['_id']
        partition = server.get('partition')

        (pod, rack) = _server_pod_rack(servername)
        pod_bucket = 'pod:{:04X}'.format(pod)
        rack_bucket = 'rack:{:04X}'.format(rack)

        _LOGGER.info('Update: %r(partition:%r) -> %r, %r',
                     servername, partition, pod_bucket, rack_bucket)

        masterapi.create_bucket(zkclient, pod_bucket, parent_id=None)
        masterapi.cell_insert_bucket(zkclient, pod_bucket)
        masterapi.create_bucket(zkclient, rack_bucket, parent_id=pod_bucket)
        masterapi.create_server(
            zkclient,
            servername,
            rack_bucket,
            partition=partition
        )

    ldap_servers = set(server['_id'] for server in servers)
    zk_servers = set(masterapi.list_servers(zkclient))
    zk_server_presence = set(zkclient.get_children(z.SERVER_PRESENCE))
    for servername in zk_servers - ldap_servers:
        if servername in zk_server_presence:
            _LOGGER.warning('%s not in LDAP but node still present, skipping.',
                            servername)
        else:
            _LOGGER.info('Delete: %s', servername)
            masterapi.delete_server(zkclient, servername)
예제 #3
0
def sync_servers():
    """Sync servers and buckets."""
    admin_srv = admin.Server(context.GLOBAL.ldap.conn)
    servers = admin_srv.list({'cell': context.GLOBAL.cell})

    for server in servers:
        servername = server['_id']

        rack = 'rack:unknown'
        building = 'building:unknown'

        traits = []
        partition = None

        masterapi.create_bucket(context.GLOBAL.zk.conn, building, None)
        masterapi.cell_insert_bucket(context.GLOBAL.zk.conn, building)
        masterapi.create_bucket(context.GLOBAL.zk.conn, rack, building)
        masterapi.create_server(context.GLOBAL.zk.conn,
                                servername,
                                rack,
                                partition=partition)