[libgovirt] Add ovirt_resource_action() method
- From: Christophe Fergeau <teuf src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgovirt] Add ovirt_resource_action() method
- Date: Wed, 11 Dec 2013 14:47:42 +0000 (UTC)
commit 125c0f761b52ec689bcee6cf064337d45a5b5d0d
Author: Christophe Fergeau <cfergeau redhat com>
Date: Tue Dec 3 19:44:40 2013 +0100
Add ovirt_resource_action() method
This will do a synchronous call to invoke an oVirt REST action. This is
a generic version of ovirt_vm_action() which has been ported to it.
govirt/ovirt-resource-private.h | 6 ++
govirt/ovirt-resource.c | 143 +++++++++++++++++++++++++++++++++++++++
govirt/ovirt-vm.c | 66 ++++--------------
3 files changed, 162 insertions(+), 53 deletions(-)
---
diff --git a/govirt/ovirt-resource-private.h b/govirt/ovirt-resource-private.h
index c026014..0766049 100644
--- a/govirt/ovirt-resource-private.h
+++ b/govirt/ovirt-resource-private.h
@@ -32,6 +32,12 @@ const char *ovirt_resource_get_action(OvirtResource *resource,
char *ovirt_resource_to_xml(OvirtResource *resource);
gboolean ovirt_resource_rest_call_sync(OvirtRestCall *call, GError **error);
+typedef gboolean (*ActionResponseParser)(RestXmlNode *node, OvirtResource *resource, GError **error);
+gboolean ovirt_resource_action(OvirtResource *resource, OvirtProxy *proxy,
+ const char *action,
+ ActionResponseParser response_parser,
+ GError **error);
+
G_END_DECLS
#endif /* __OVIRT_RESOURCE_PRIVATE_H__ */
diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index fca06e8..a8cb13c 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -585,3 +585,146 @@ gboolean ovirt_resource_update_finish(OvirtResource *resource,
return ovirt_rest_call_finish(result, err);
}
+
+
+enum OvirtResponseStatus {
+ OVIRT_RESPONSE_UNKNOWN,
+ OVIRT_RESPONSE_FAILED,
+ OVIRT_RESPONSE_PENDING,
+ OVIRT_RESPONSE_IN_PROGRESS,
+ OVIRT_RESPONSE_COMPLETE
+};
+
+static gboolean parse_action_response(RestProxyCall *call, OvirtResource *resource,
+ ActionResponseParser response_parser,
+ GError **error);
+
+gboolean
+ovirt_resource_action(OvirtResource *resource, OvirtProxy *proxy,
+ const char *action,
+ ActionResponseParser response_parser,
+ GError **error)
+{
+ RestProxyCall *call;
+ const char *function;
+
+ g_return_val_if_fail(OVIRT_IS_RESOURCE(resource), FALSE);
+ g_return_val_if_fail(action != NULL, FALSE);
+ g_return_val_if_fail(OVIRT_IS_PROXY(proxy), FALSE);
+ g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
+
+ function = ovirt_resource_get_action(OVIRT_RESOURCE(resource), action);
+ function = ovirt_utils_strip_api_base_dir(function);
+ g_return_val_if_fail(function != NULL, FALSE);
+
+ call = REST_PROXY_CALL(ovirt_action_rest_call_new(REST_PROXY(proxy)));
+ rest_proxy_call_set_method(call, "POST");
+ rest_proxy_call_set_function(call, function);
+ rest_proxy_call_add_param(call, "async", "false");
+
+ if (!rest_proxy_call_sync(call, error)) {
+ GError *call_error = NULL;
+ g_warning("Error while running %s on %p", action, resource);
+ /* Even in error cases we may have a response body describing
+ * the failure, try to parse that */
+ parse_action_response(call, resource, response_parser, &call_error);
+ if (call_error != NULL) {
+ g_clear_error(error);
+ g_propagate_error(error, call_error);
+ }
+
+ g_object_unref(G_OBJECT(call));
+ return FALSE;
+ }
+
+ parse_action_response(call, resource, response_parser, error);
+
+ g_object_unref(G_OBJECT(call));
+
+ return TRUE;
+}
+
+
+static enum OvirtResponseStatus parse_action_status(RestXmlNode *root,
+ GError **error)
+{
+ RestXmlNode *node;
+ const char *status_key = g_intern_string("status");
+ const char *state_key = g_intern_string("state");
+
+ g_return_val_if_fail(g_strcmp0(root->name, "action") == 0,
+ OVIRT_RESPONSE_UNKNOWN);
+ g_return_val_if_fail(error == NULL || *error == NULL,
+ OVIRT_RESPONSE_UNKNOWN);
+
+ node = g_hash_table_lookup(root->children, status_key);
+ if (node == NULL) {
+ g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "could not find 'status' node");
+ g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+ }
+ node = g_hash_table_lookup(node->children, state_key);
+ if (node == NULL) {
+ g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "could not find 'state' node");
+ g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+ }
+ g_debug("State: %s\n", node->content);
+ if (g_strcmp0(node->content, "complete") == 0) {
+ return OVIRT_RESPONSE_COMPLETE;
+ } else if (g_strcmp0(node->content, "pending") == 0) {
+ g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_ACTION_FAILED, "action is pending");
+ return OVIRT_RESPONSE_PENDING;
+ } else if (g_strcmp0(node->content, "in_progress") == 0) {
+ g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_ACTION_FAILED, "action is in progress");
+ return OVIRT_RESPONSE_IN_PROGRESS;
+ } else if (g_strcmp0(node->content, "failed") == 0) {
+ g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_ACTION_FAILED, "action has failed");
+ return OVIRT_RESPONSE_FAILED;
+ }
+
+ g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "unknown action failure");
+ g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+}
+
+
+static gboolean
+parse_action_response(RestProxyCall *call, OvirtResource *resource,
+ ActionResponseParser response_parser, GError **error)
+{
+ RestXmlNode *root;
+ gboolean result;
+
+ result = FALSE;
+ root = ovirt_rest_xml_node_from_call(call);
+
+ if (g_strcmp0(root->name, "action") == 0) {
+ enum OvirtResponseStatus status;
+
+ status = parse_action_status(root, error);
+ if (status == OVIRT_RESPONSE_COMPLETE) {
+ if (response_parser) {
+ result = response_parser(root, resource, error);
+ } else {
+ result = TRUE;
+ }
+ } if (status == OVIRT_RESPONSE_FAILED) {
+ const char *fault_key = g_intern_string("fault");
+ GError *fault_error = NULL;
+ RestXmlNode *fault_node = NULL;
+
+ fault_node = g_hash_table_lookup(root->children, fault_key);
+ if (fault_node != NULL) {
+ ovirt_utils_gerror_from_xml_fault(fault_node, &fault_error);
+ if (fault_error != NULL) {
+ g_clear_error(error);
+ g_propagate_error(error, fault_error);
+ }
+ }
+ }
+ } else {
+ g_warn_if_reached();
+ }
+
+ rest_xml_node_unref(root);
+
+ return result;
+}
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 7f83384..be39eb7 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -30,11 +30,10 @@
#include "govirt-private.h"
-typedef gboolean (*ActionResponseParser)(RestXmlNode *node, OvirtVm *vm, GError **error);
static gboolean parse_action_response(RestProxyCall *call, OvirtVm *vm,
ActionResponseParser response_parser,
GError **error);
-static gboolean parse_ticket_status(RestXmlNode *root, OvirtVm *vm,
+static gboolean parse_ticket_status(RestXmlNode *root, OvirtResource *resource,
GError **error);
#define OVIRT_VM_GET_PRIVATE(obj) \
@@ -307,68 +306,28 @@ ovirt_vm_stop_finish(OvirtVm *vm, GAsyncResult *result, GError **err)
}
-static gboolean
-ovirt_vm_action(OvirtVm *vm, OvirtProxy *proxy, const char *action,
- ActionResponseParser response_parser, GError **error)
-{
- RestProxyCall *call;
- const char *function;
-
- g_return_val_if_fail(OVIRT_IS_VM(vm), FALSE);
- g_return_val_if_fail(action != NULL, FALSE);
- g_return_val_if_fail(OVIRT_IS_PROXY(proxy), FALSE);
- g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
-
- function = ovirt_resource_get_action(OVIRT_RESOURCE(vm), action);
- function = ovirt_utils_strip_api_base_dir(function);
- g_return_val_if_fail(function != NULL, FALSE);
-
- call = REST_PROXY_CALL(ovirt_action_rest_call_new(REST_PROXY(proxy)));
- rest_proxy_call_set_method(call, "POST");
- rest_proxy_call_set_function(call, function);
- rest_proxy_call_add_param(call, "async", "false");
-
- if (!rest_proxy_call_sync(call, error)) {
- GError *call_error = NULL;
- g_warning("Error while running %s on %p", action, vm);
- /* Even in error cases we may have a response body describing
- * the failure, try to parse that */
- parse_action_response(call, vm, response_parser, &call_error);
- if (call_error != NULL) {
- g_clear_error(error);
- g_propagate_error(error, call_error);
- }
-
- g_object_unref(G_OBJECT(call));
- return FALSE;
- }
-
- parse_action_response(call, vm, response_parser, error);
-
- g_object_unref(G_OBJECT(call));
-
- return TRUE;
-}
-
gboolean ovirt_vm_get_ticket(OvirtVm *vm, OvirtProxy *proxy, GError **error)
{
- return ovirt_vm_action(vm, proxy, "ticket",
- parse_ticket_status,
- error);
+ return ovirt_resource_action(OVIRT_RESOURCE(vm), proxy, "ticket",
+ parse_ticket_status,
+ error);
}
gboolean ovirt_vm_start(OvirtVm *vm, OvirtProxy *proxy, GError **error)
{
- return ovirt_vm_action(vm, proxy, "start", NULL, error);
+ return ovirt_resource_action(OVIRT_RESOURCE(vm), proxy, "start",
+ NULL, error);
}
gboolean ovirt_vm_stop(OvirtVm *vm, OvirtProxy *proxy, GError **error)
{
- return ovirt_vm_action(vm, proxy, "stop", NULL, error);
+ return ovirt_resource_action(OVIRT_RESOURCE(vm), proxy, "stop",
+ NULL, error);
}
-static gboolean parse_ticket_status(RestXmlNode *root, OvirtVm *vm, GError **error)
+static gboolean parse_ticket_status(RestXmlNode *root, OvirtResource *resource, GError **error)
{
+ OvirtVm *vm;
RestXmlNode *node;
const char *ticket_key = g_intern_string("ticket");
const char *value_key = g_intern_string("value");
@@ -376,9 +335,10 @@ static gboolean parse_ticket_status(RestXmlNode *root, OvirtVm *vm, GError **err
OvirtVmDisplay *display;
g_return_val_if_fail(root != NULL, FALSE);
- g_return_val_if_fail(vm != NULL, FALSE);
+ g_return_val_if_fail(OVIRT_IS_VM(resource), FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+ vm = OVIRT_VM(resource);
root = g_hash_table_lookup(root->children, ticket_key);
if (root == NULL) {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "could not find 'ticket' node");
@@ -467,7 +427,7 @@ parse_action_response(RestProxyCall *call, OvirtVm *vm,
status = parse_action_status(root, error);
if (status == OVIRT_RESPONSE_COMPLETE) {
if (response_parser) {
- result = response_parser(root, vm, error);
+ result = response_parser(root, OVIRT_RESOURCE(vm), error);
} else {
result = TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]