'Provision cloud cluster for acceptance tests.
:return Cluster: The cluster to connect to for acceptance tests.'

@inlineCallbacks
def start_cluster(self, reactor):

    print 'Assigning    random    tag:', self.random_tag
    for index in range(self.num_nodes):
        name = self._make_node_name(self.random_tag, index)
        try:
            print ('Creating    node    %d:    %s' % (index, name))
            node = self.provisioner.create_node(name=name, distribution=self.distribution, metadata=self.metadata)
        except:
            print ('Error    creating    node    %d:    %s' % (index, name))
            print 'It    may    have    leaked    into    the    cloud.'
            raise
        (yield remove_known_host(reactor, node.address))
        self.nodes.append(node)
        del node
    commands = parallel([node.provision(package_source=self.package_source, variants=self.variants) for node in self.nodes])
    if (self.dataset_backend == backends.ZFS):
        zfs_commands = parallel([configure_zfs(node, variants=self.variants) for node in self.nodes])
        commands = commands.on(success=(lambda _: zfs_commands))
    (yield perform(make_dispatcher(reactor), commands))
    cluster = (yield configured_cluster_for_nodes(reactor, generate_certificates(self.identity.name, self.identity.id, self.nodes, self.cert_path), self.nodes, self.dataset_backend, self.dataset_backend_configuration, save_backend_configuration(self.dataset_backend, self.dataset_backend_configuration), logging_config=self.config.get('logging')))
    returnValue(cluster)
