+ """
+ flat_disks = []
+ for disk in snap_disks:
+ flat_disks.append(disk.ToDict())
+
+ return self._SingleNodeCall(node, "finalize_export",
+ [self._InstDict(instance), flat_disks])
+
+ def call_export_info(self, node, path):
+ """Queries the export information in a given path.
+
+ This is a single-node call.
+
+ """
+ result = self._SingleNodeCall(node, "export_info", [path])
+ if not result.failed and result.data:
+ result.data = objects.SerializableConfigParser.Loads(str(result.data))
+ return result
+
+ def call_instance_os_import(self, node, inst, src_node, src_images,
+ cluster_name):
+ """Request the import of a backup into an instance.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "instance_os_import",
+ [self._InstDict(inst), src_node, src_images,
+ cluster_name])
+
+ def call_export_list(self, node_list):
+ """Gets the stored exports list.
+
+ This is a multi-node call.
+
+ """
+ return self._MultiNodeCall(node_list, "export_list", [])
+
+ def call_export_remove(self, node, export):
+ """Requests removal of a given export.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "export_remove", [export])
+
+ @classmethod
+ def call_node_leave_cluster(cls, node):
+ """Requests a node to clean the cluster information it has.
+
+ This will remove the configuration information from the ganeti data
+ dir.
+
+ This is a single-node call.
+
+ """
+ return cls._StaticSingleNodeCall(node, "node_leave_cluster", [])
+
+ def call_node_volumes(self, node_list):
+ """Gets all volumes on node(s).
+
+ This is a multi-node call.
+
+ """
+ return self._MultiNodeCall(node_list, "node_volumes", [])
+
+ def call_node_demote_from_mc(self, node):
+ """Demote a node from the master candidate role.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "node_demote_from_mc", [])
+
+
+ def call_node_powercycle(self, node, hypervisor):
+ """Tries to powercycle a node.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
+
+
+ def call_test_delay(self, node_list, duration):
+ """Sleep for a fixed time on given node(s).
+
+ This is a multi-node call.
+
+ """
+ return self._MultiNodeCall(node_list, "test_delay", [duration])
+
+ def call_file_storage_dir_create(self, node, file_storage_dir):
+ """Create the given file storage directory.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "file_storage_dir_create",
+ [file_storage_dir])
+
+ def call_file_storage_dir_remove(self, node, file_storage_dir):
+ """Remove the given file storage directory.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "file_storage_dir_remove",
+ [file_storage_dir])
+
+ def call_file_storage_dir_rename(self, node, old_file_storage_dir,
+ new_file_storage_dir):
+ """Rename file storage directory.
+
+ This is a single-node call.
+
+ """
+ return self._SingleNodeCall(node, "file_storage_dir_rename",
+ [old_file_storage_dir, new_file_storage_dir])
+
+ @classmethod
+ def call_jobqueue_update(cls, node_list, address_list, file_name, content):
+ """Update job queue.
+
+ This is a multi-node call.
+
+ """
+ return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
+ [file_name, cls._Compress(content)],
+ address_list=address_list)
+
+ @classmethod
+ def call_jobqueue_purge(cls, node):
+ """Purge job queue.
+
+ This is a single-node call.
+
+ """
+ return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
+
+ @classmethod
+ def call_jobqueue_rename(cls, node_list, address_list, rename):
+ """Rename a job queue file.
+
+ This is a multi-node call.
+
+ """
+ return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
+ address_list=address_list)
+
+ @classmethod
+ def call_jobqueue_set_drain(cls, node_list, drain_flag):
+ """Set the drain flag on the queue.
+
+ This is a multi-node call.
+
+ @type node_list: list
+ @param node_list: the list of nodes to query
+ @type drain_flag: bool
+ @param drain_flag: if True, will set the drain flag, otherwise reset it.
+
+ """
+ return cls._StaticMultiNodeCall(node_list, "jobqueue_set_drain",
+ [drain_flag])
+
+ def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
+ """Validate the hypervisor params.
+
+ This is a multi-node call.
+
+ @type node_list: list
+ @param node_list: the list of nodes to query
+ @type hvname: string
+ @param hvname: the hypervisor name
+ @type hvparams: dict
+ @param hvparams: the hypervisor parameters to be validated
+
+ """
+ cluster = self._cfg.GetClusterInfo()
+ hv_full = cluster.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
+ return self._MultiNodeCall(node_list, "hypervisor_validate_params",
+ [hvname, hv_full])