Ejemplo n.º 1
0
    def __init__(self, config_dir, count, osds_per_host, port=8761, prefix=PREFIX, domain=DOMAIN):
        super(MinionSim, self).__init__()
        self._config_dir = config_dir
        self._count = count
        self._server = None
        self._server_available = threading.Event()
        self.minions = {}

        def get_dns(index):
            host = "{0}{1:03d}".format(prefix, index)
            return host, "{0}.{1}".format(host, domain)

        config_file = os.path.join(self._config_dir, 'cluster.json')
        self.cluster = CephCluster(config_file)
        if not os.path.exists(config_file):
            self.cluster.create([get_dns(i)[1] for i in range(0, self._count)], osds_per_host=osds_per_host)
            self.cluster.save()

        # An XMLRPC service for the minions' fake ceph plugins to
        # get their state
        self._server = SimpleXMLRPCServer(("localhost", port), allow_none=True)
        self._server.register_instance(self.cluster)

        rpc_url = "http://localhost:%s" % port

        for i in range(0, self._count):
            hostname, fqdn = get_dns(i)
            self.minions[fqdn] = MinionLauncher(rpc_url, self._config_dir, hostname, fqdn, self.cluster)

        # Quick smoke test that these methods aren't going
        # to throw exceptions (rather stop now than get exceptions
        # remotely)
        for minion in self.minions.values():
            self.cluster.get_stats(minion.fqdn)
Ejemplo n.º 2
0
    def setUp(self):
        super(TestMon, self).setUp()

        # I'm using CephCluster to generate the status objects to use as fixtures, I'm not
        # actually running the simulator or anything like that because this is a unit test.
        cluster = CephCluster()
        cluster.create(self.SERVERS)
        self.fsid = cluster.fsid

        # This will appear to be a completely happy healthy quorum of mons
        self.mon_status = msgpack.unpackb(
            cluster.get_cluster_object('ceph_fake', 'mon_status',
                                       None).data)['data']

        # XXX hmm, perhaps synthesizing this stuff should go into
        # ceph_cluster and then it be sensibly kept up to date with
        # synthesized quorum changes.
        self.server1_status = deepcopy(self.mon_status)
        self.server2_status = deepcopy(self.mon_status)
        self.server3_status = deepcopy(self.mon_status)
        for (server_status, name, rank, state) in [
            (self.server1_status, 'server1', 0, 'leader'),
            (self.server2_status, 'server2', 1, 'peon'),
            (self.server3_status, 'server3', 2, 'peon'),
        ]:
            server_status['name'] = name
            server_status['rank'] = rank
            server_status['state'] = state

        self.service_status = [{
            'id': 'server1',
            'type': 'mon',
            'cluster': cluster.name,
            'fsid': cluster.fsid,
            'status': self.server1_status,
            'server': 'server1',
            'running': True
        }, {
            'id': 'server1',
            'type': 'mon',
            'cluster': cluster.name,
            'fsid': cluster.fsid,
            'status': self.server2_status,
            'server': 'server2',
            'running': True
        }, {
            'id': 'server1',
            'type': 'mon',
            'cluster': cluster.name,
            'fsid': cluster.fsid,
            'status': self.server3_status,
            'server': 'server3',
            'running': True
        }]
        self.rpc.get_sync_object = mock.Mock(return_value=self.mon_status)
        self.rpc.status_by_service = mock.Mock(
            return_value=self.service_status)
Ejemplo n.º 3
0
class MinionSim(threading.Thread):
    def __init__(self, config_dir, count, osds_per_host, port=8761, prefix=PREFIX, domain=DOMAIN):
        super(MinionSim, self).__init__()
        self._config_dir = config_dir
        self._count = count
        self._server = None
        self._server_available = threading.Event()
        self.minions = {}

        def get_dns(index):
            host = "{0}{1:03d}".format(prefix, index)
            return host, "{0}.{1}".format(host, domain)

        config_file = os.path.join(self._config_dir, 'cluster.json')
        self.cluster = CephCluster(config_file)
        if not os.path.exists(config_file):
            self.cluster.create([get_dns(i)[1] for i in range(0, self._count)], osds_per_host=osds_per_host)
            self.cluster.save()

        # An XMLRPC service for the minions' fake ceph plugins to
        # get their state
        self._server = SimpleXMLRPCServer(("localhost", port), allow_none=True)
        self._server.register_instance(self.cluster)

        rpc_url = "http://localhost:%s" % port

        for i in range(0, self._count):
            hostname, fqdn = get_dns(i)
            self.minions[fqdn] = MinionLauncher(rpc_url, self._config_dir, hostname, fqdn, self.cluster)

        # Quick smoke test that these methods aren't going
        # to throw exceptions (rather stop now than get exceptions
        # remotely)
        for minion in self.minions.values():
            self.cluster.get_stats(minion.fqdn)

    def get_minion_fqdns(self):
        return [m.fqdn for m in self.minions.values()]

    def start(self):
        super(MinionSim, self).start()
        self._server_available.wait()

    def run(self):
        # A thread to generate some synthetic activity on the synthetic cluster
        load_gen = LoadGenerator(self.cluster)
        load_gen.start()

        self.start_minions()

        self._server_available.set()

        log.debug("Starting XMLRPC server...")
        self._server.serve_forever()
        self._server.server_close()
        log.debug("XMLRPC server terminated, stopping threads")

        log.debug("Stopping load gen")
        load_gen.stop()
        load_gen.join()

        log.debug("Stopping minions")
        self.halt_minions()

        log.debug("Saving state")
        self.cluster.save()
        log.debug("Complete.")

    def stop(self):
        # FIXME should stop the minions before the XMLRPC server, because otherwise
        # minions start getting XMLRPC errors
        self._server.shutdown()

    def halt_minions(self):
        for minion in self.minions.values():
            minion.stop()
        for minion in self.minions.values():
            minion.join()

    def start_minions(self):
        for minion in self.minions.values():
            minion.start()

    def halt_minion(self, minion_id):
        self.minions[minion_id].stop()
        self.minions[minion_id].join()

    def start_minion(self, minion_id):
        self.minions[minion_id].start()