@skipIf(True,
            "Shutting down a node invalidates a public IP, which breaks all "
            "kinds of things. So skip for now.")
    @require_moving_backend
    @run_test_with(async_runner(timeout=timedelta(minutes=6)))
    @require_cluster(2)
    def test_dataset_move_from_dead_node(self, cluster):
        api = get_backend_api(cluster.cluster_uuid)
        if not ICloudAPI.providedBy(api):
            raise SkipTest(
                "Backend doesn't support ICloudAPI; therefore it might support"
                " moving from dead node but as first pass we assume it "
                "doesn't.")

        # Find a node which is not running the control service.
        # If the control node is shut down we won't be able to move anything!
        node = list(node for node in cluster.nodes
                    if node.public_address !=
                    cluster.control_node.public_address)[0]
        other_node = list(other_node for other_node in cluster.nodes
                          if other_node != node)[0]
        waiting_for_create = create_dataset(self, cluster, node=node)

        def startup_node(node_id):
            api.start_node(node_id)
            # Wait for node to boot up:; we presume Flocker getting going after
            # SSH is available will be pretty quick:
            return loop_until(reactor, verify_socket(node.public_address, 22))

        # Once created, shut down origin node and then request to move the
        # dataset to node2:
        def shutdown(dataset):
            live_node_ids = set(api.list_live_nodes())
            d = node.shutdown()
            # Wait for shutdown to be far enough long that node is down:
            d.addCallback(
                lambda _:
                loop_until(reactor, lambda:
                           set(api.list_live_nodes()) != live_node_ids))
            # Schedule node start up:
            d.addCallback(
                lambda _: self.addCleanup(
                    startup_node,
                    (live_node_ids - set(api.list_live_nodes())).pop()))
            d.addCallback(lambda _: dataset)
            return d
        waiting_for_shutdown = waiting_for_create.addCallback(shutdown)

        def move_dataset(dataset):
            dataset_moving = cluster.client.move_dataset(
                UUID(other_node.uuid), dataset.dataset_id)

            # Wait for the dataset to be moved; we expect the state to
            # match that of the originally created dataset in all ways
            # other than the location.
            moved_dataset = dataset.set(
                primary=UUID(other_node.uuid))
            dataset_moving.addCallback(
                lambda dataset: cluster.wait_for_dataset(moved_dataset))
            return dataset_moving

        waiting_for_shutdown.addCallback(move_dataset)
        return waiting_for_shutdown
A dataset can be moved from a dead node to a live node.
dataset/ETHPy150Open ClusterHQ/flocker/flocker/acceptance/endtoend/test_dataset.py/DatasetAPITests.test_dataset_move_from_dead_node