[PATCH 09/16] virsh: Add new command `nwfilter-desc`

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This command can be used to view/modify the `<title>` and
`<description>` fields of the NWFilter object.

Signed-off-by: K Shiva Kiran <shiva_kr@xxxxxxxxxx>
---
 tools/virsh-nwfilter.c | 209 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 209 insertions(+)

diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c
index 92b2b7b3bc..615d126def 100644
--- a/tools/virsh-nwfilter.c
+++ b/tools/virsh-nwfilter.c
@@ -26,6 +26,7 @@
 #include "viralloc.h"
 #include "virfile.h"
 #include "vsh-table.h"
+#include "virxml.h"
 
 virNWFilterPtr
 virshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
@@ -345,6 +346,53 @@ virshNWFilterListCollect(vshControl *ctl,
     return list;
 }
 
+/* extract description or title from nwfilter xml */
+static char *
+virshGetNWFilterDescription(vshControl *ctl, virNWFilterPtr nwfilter,
+                            bool title, unsigned int flags,
+                            unsigned int queryflags)
+{
+    char *desc = NULL;
+    g_autoptr(xmlDoc) doc = NULL;
+    g_autoptr(xmlXPathContext) ctxt = NULL;
+    int type;
+
+    if (title)
+        type = VIR_NWFILTER_METADATA_TITLE;
+    else
+        type = VIR_NWFILTER_METADATA_DESCRIPTION;
+
+    if ((desc = virNWFilterGetMetadata(nwfilter, type, NULL, flags))) {
+        return desc;
+    } else {
+        int errCode = virGetLastErrorCode();
+
+        if (errCode == VIR_ERR_NO_NWFILTER_METADATA) {
+            desc = g_strdup("");
+            vshResetLibvirtError();
+            return desc;
+        }
+
+        if (errCode != VIR_ERR_NO_SUPPORT)
+            return desc;
+    }
+
+    /* fall back to xml */
+    if (virshNWFilterGetXMLFromNWFilter(ctl, nwfilter, queryflags, &doc, &ctxt) < 0)
+        return NULL;
+
+    if (title)
+        desc = virXPathString("string(./title[1])", ctxt);
+    else
+        desc = virXPathString("string(./description[1])", ctxt);
+
+    if (!desc)
+        desc = g_strdup("");
+
+    return desc;
+}
+
+
 /*
  * "nwfilter-list" command
  */
@@ -768,6 +816,161 @@ cmdNWFilterBindingList(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
 }
 
 
+/*
+ * "nwfilter-desc" command
+ */
+static const vshCmdInfo info_nwfilter_desc[] = {
+    {.name = "help",
+     .data = N_("show or set network filter's description or title")
+    },
+    {.name = "desc",
+     .data = N_("Allows setting or modifying the description or title of a network filter.")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_nwfilter_desc[] = {
+    {.name = "nwfilter",
+     .type = VSH_OT_DATA,
+     .flags = VSH_OFLAG_REQ,
+     .help = N_("network filter name or uuid"),
+     .completer = virshNWFilterNameCompleter,
+    },
+    {.name = "title",
+     .type = VSH_OT_BOOL,
+     .help = N_("modify/get the title instead of description")
+    },
+    {.name = "edit",
+     .type = VSH_OT_BOOL,
+     .help = N_("open an editor to modify the description")
+    },
+    {.name = "remove",
+     .type = VSH_OT_BOOL,
+     .help = N_("remove the element")
+    },
+    {.name = "new-desc",
+     .type = VSH_OT_ARGV,
+     .help = N_("message")
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdNWFilterDesc(vshControl *ctl, const vshCmd *cmd)
+{
+    g_autoptr(virshNWFilter) nwfilter = NULL;
+    bool title = vshCommandOptBool(cmd, "title");
+    bool edit = vshCommandOptBool(cmd, "edit");
+    bool remove = vshCommandOptBool(cmd, "remove");
+    int type;
+    g_autofree char *descArg = NULL;
+    const vshCmdOpt *opt = NULL;
+    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+    unsigned int flags = 0;
+    unsigned int queryflags = 0;
+
+    VSH_EXCLUSIVE_OPTIONS("remove", "edit");
+
+    if (!(nwfilter = virshCommandOptNWFilter(ctl, cmd, NULL)))
+        return false;
+
+    if (title)
+        type = VIR_NWFILTER_METADATA_TITLE;
+    else
+        type = VIR_NWFILTER_METADATA_DESCRIPTION;
+
+
+    while ((opt = vshCommandOptArgv(ctl, cmd, opt)))
+        virBufferAsprintf(&buf, "%s ", opt->data);
+
+    virBufferTrim(&buf, " ");
+
+    descArg = virBufferContentAndReset(&buf);
+
+    if (remove) {
+
+        if (descArg) {
+            vshPrintExtra(ctl, "unexpected data: \'%s\'", descArg);
+            return false;
+        }
+
+        if (virNWFilterSetMetadata(nwfilter, type, "", NULL, NULL, flags) < 0)
+            goto error;
+
+        vshPrintExtra(ctl, "%s removed successfully", title ? "Title" : "Description");
+
+    } else if (edit || descArg) {
+
+        g_autofree char *descNWFilter = NULL;
+        g_autofree char *descNew = NULL;
+
+        if (!(descNWFilter = virshGetNWFilterDescription(ctl, nwfilter,
+                                                         title, flags, queryflags)))
+            return false;
+
+        if (!descArg)
+            descArg = g_strdup(descNWFilter);
+
+        if (edit) {
+            g_autoptr(vshTempFile) tmp = NULL;
+            g_autofree char *desc_edited = NULL;
+            char *tmpstr;
+
+            /* Create and open a temporary file. */
+            if (!(tmp = vshEditWriteToTempFile(ctl, descArg)))
+                return false;
+
+            /* Start the editor. */
+            if (vshEditFile(ctl, tmp) == -1)
+                return false;
+
+            /* Read back the edited file. */
+            if (!(desc_edited = vshEditReadBackFile(ctl, tmp)))
+                return false;
+
+            /* strip a possible newline at the end */
+            if (title &&
+                (tmpstr = strrchr(desc_edited, '\n')) &&
+                *(tmpstr+1) == '\0')
+                *tmpstr = '\0';
+
+            /* Check whether XML has changed */
+            if (STREQ(descNWFilter, desc_edited)) {
+                vshPrintExtra(ctl, "Network filter %s has not changed", title ? "title" : "description");
+                return true;
+            }
+
+            descNew = g_steal_pointer(&desc_edited);
+
+        } else {
+            descNew = g_steal_pointer(&descArg);
+        }
+
+        if (virNWFilterSetMetadata(nwfilter, type, descNew, NULL, NULL, flags) < 0)
+            goto error;
+
+        vshPrintExtra(ctl, "Network filter %s updated successfully", title ? "title" : "description");
+
+    } else {
+        g_autofree char *desc = virshGetNWFilterDescription(ctl, nwfilter, title, flags, queryflags);
+        if (!desc)
+            return false;
+
+        if (strlen(desc) > 0) {
+            vshPrint(ctl, "%s", desc);
+        } else {
+            vshPrintExtra(ctl, _("No %1$s for network filter: %2$s"), title ? "title" : "description", virNWFilterGetName(nwfilter));
+        }
+    }
+
+    return true;
+
+    error:
+        vshError(ctl, "Failed to set %s for network filter", title ? "title" : "description");
+        return false;
+}
+
+
 const vshCmdDef nwfilterCmds[] = {
     {.name = "nwfilter-define",
      .handler = cmdNWFilterDefine,
@@ -823,5 +1026,11 @@ const vshCmdDef nwfilterCmds[] = {
      .info = info_nwfilter_binding_list,
      .flags = 0
     },
+    {.name = "nwfilter-desc",
+     .handler = cmdNWFilterDesc,
+     .opts = opts_nwfilter_desc,
+     .info = info_nwfilter_desc,
+     .flags = 0
+    },
     {.name = NULL}
 };
-- 
2.42.0





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux