]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
ch: add/use virCHMonitorPut function
authorStefan Kober <stefan.kober@cyberus-technology.de>
Thu, 4 Sep 2025 12:10:27 +0000 (14:10 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 8 Sep 2025 14:40:08 +0000 (16:40 +0200)
This allows users to call API endpoints that require passing data in a
generic way. Previously, only virCHMonitorPutNoContent was offered.

On-behalf-of: SAP stefan.kober@sap.com
Signed-off-by: Stefan Kober <stefan.kober@cyberus-technology.de>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/ch/ch_monitor.c

index 89cd23005346243ed373716fb77e44c97c0dd2e8..a16d29979ffcc80192034670189d73efa9c97a55 100644 (file)
@@ -62,6 +62,12 @@ VIR_ONCE_GLOBAL_INIT(virCHMonitor);
 int virCHMonitorShutdownVMM(virCHMonitor *mon);
 int virCHMonitorPutNoContent(virCHMonitor *mon, const char *endpoint,
                              domainLogContext *logCtxt);
+static int
+virCHMonitorPut(virCHMonitor *mon,
+                const char *endpoint,
+                virJSONValue *payload,
+                domainLogContext *logCtxt,
+                virJSONValue **answer);
 
 static int
 virCHMonitorBuildCPUJson(virJSONValue *content, virDomainDef *vmdef)
@@ -868,12 +874,16 @@ curl_callback(void *contents, size_t size, size_t nmemb, void *userp)
     return content_size;
 }
 
-int
-virCHMonitorPutNoContent(virCHMonitor *mon, const char *endpoint,
-                         domainLogContext *logCtxt)
+static int
+virCHMonitorPut(virCHMonitor *mon,
+                const char *endpoint,
+                virJSONValue *payload,
+                domainLogContext *logCtxt,
+                virJSONValue **answer)
 {
     VIR_LOCK_GUARD lock = virObjectLockGuard(mon);
     g_autofree char *url = NULL;
+    g_autofree char *payload_str = NULL;
     int responseCode = 0;
     int ret = -1;
     struct curl_data data = {0};
@@ -891,28 +901,56 @@ virCHMonitorPutNoContent(virCHMonitor *mon, const char *endpoint,
     curl_easy_setopt(mon->handle, CURLOPT_INFILESIZE, 0L);
 
     headers = curl_slist_append(headers, "Accept: application/json");
+
     curl_easy_setopt(mon->handle, CURLOPT_HTTPHEADER, headers);
     curl_easy_setopt(mon->handle, CURLOPT_WRITEFUNCTION, curl_callback);
     curl_easy_setopt(mon->handle, CURLOPT_WRITEDATA, (void *)&data);
 
+    if (payload) {
+        payload_str = virJSONValueToString(payload, false);
+        curl_easy_setopt(mon->handle, CURLOPT_POSTFIELDS, payload_str);
+        curl_easy_setopt(mon->handle, CURLOPT_CUSTOMREQUEST, "PUT");
+        headers = curl_slist_append(headers, "Content-Type: application/json");
+    }
+
     responseCode = virCHMonitorCurlPerform(mon->handle);
 
+    data.content = g_realloc(data.content, data.size + 1);
+    data.content[data.size] = '\0';
+
     if (logCtxt && data.size) {
         /* Do this to append a NULL char at the end of data */
-        data.content = g_realloc(data.content, data.size + 1);
-        data.content[data.size] = 0;
         domainLogContextWrite(logCtxt, "HTTP response code from CH: %d\n", responseCode);
         domainLogContextWrite(logCtxt, "Response = %s\n", data.content);
     }
 
-    if (responseCode == 200 || responseCode == 204)
-        ret = 0;
+    if (responseCode != 200 && responseCode != 204) {
+        ret = -1;
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Invalid HTTP response code from CH: %1$d"),
+                       responseCode);
+        goto cleanup;
+    }
 
-    curl_slist_free_all(headers);
+    if (answer)
+        *answer = virJSONValueFromString(data.content);
 
+    ret = 0;
+
+ cleanup:
+    curl_slist_free_all(headers);
+    g_free(data.content);
     return ret;
 }
 
+int
+virCHMonitorPutNoContent(virCHMonitor *mon,
+                         const char *endpoint,
+                         domainLogContext *logCtxt)
+{
+    return virCHMonitorPut(mon, endpoint, NULL, logCtxt, NULL);
+}
+
 static int
 virCHMonitorGet(virCHMonitor *mon, const char *endpoint, virJSONValue **response)
 {