[libvirt] [libvirt-dbus][PATCH v4 1/2] Introduce Domain Snapshot Interface

2019-11-04 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/meson.build|  1 +
 data/org.libvirt.DomainSnapshot.xml |  7 +++
 src/connect.c   |  6 +++
 src/connect.h   |  1 +
 src/domainsnapshot.c| 75 +
 src/domainsnapshot.h|  9 
 src/meson.build |  1 +
 src/util.c  | 53 
 src/util.h  | 16 ++
 9 files changed, 169 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h

diff --git a/data/meson.build b/data/meson.build
index 42a6799..0bd6338 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -1,6 +1,7 @@
 install_data(
 'org.libvirt.Connect.xml',
 'org.libvirt.Domain.xml',
+'org.libvirt.DomainSnapshot.xml',
 'org.libvirt.Interface.xml',
 'org.libvirt.Network.xml',
 'org.libvirt.NodeDevice.xml',
diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
new file mode 100644
index 000..8ba059f
--- /dev/null
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -0,0 +1,7 @@
+http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd;>
+
+
+  
+  
+
diff --git a/src/connect.c b/src/connect.c
index f8f76a2..b40b0ba 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -1,5 +1,6 @@
 #include "connect.h"
 #include "domain.h"
+#include "domainsnapshot.h"
 #include "events.h"
 #include "interface.h"
 #include "network.h"
@@ -2002,6 +2003,7 @@ virtDBusConnectFree(virtDBusConnect *connect)
 virtDBusConnectClose(connect, TRUE);
 
 g_free(connect->domainPath);
+g_free(connect->domainSnapshotPath);
 g_free(connect->interfacePath);
 g_free(connect->networkPath);
 g_free(connect->nodeDevPath);
@@ -2062,6 +2064,10 @@ virtDBusConnectNew(virtDBusConnect **connectp,
 if (error && *error)
 return;
 
+virtDBusDomainSnapshotRegister(connect, error);
+if (error && *error)
+return;
+
 virtDBusInterfaceRegister(connect, error);
 if (error && *error)
 return;
diff --git a/src/connect.h b/src/connect.h
index 829bd57..74c89cf 100644
--- a/src/connect.h
+++ b/src/connect.h
@@ -13,6 +13,7 @@ struct virtDBusConnect {
 const gchar *uri;
 const gchar *connectPath;
 gchar *domainPath;
+gchar *domainSnapshotPath;
 gchar *interfacePath;
 gchar *networkPath;
 gchar *nodeDevPath;
diff --git a/src/domainsnapshot.c b/src/domainsnapshot.c
new file mode 100644
index 000..c523c9e
--- /dev/null
+++ b/src/domainsnapshot.c
@@ -0,0 +1,75 @@
+#include "domainsnapshot.h"
+#include "util.h"
+
+#include 
+
+static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
+{ 0 }
+};
+
+static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
+{ 0 }
+};
+
+static gchar **
+virtDBusDomainSnapshotEnumerate(gpointer userData)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomainPtr) domains = NULL;
+gint numDoms = 0;
+GPtrArray *list = NULL;
+
+if (!virtDBusConnectOpen(connect, NULL))
+return NULL;
+
+numDoms = virConnectListAllDomains(connect->connection, , 0);
+if (numDoms <= 0)
+return NULL;
+
+list = g_ptr_array_new();
+
+for (gint i = 0; i < numDoms; i++) {
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+gint numSnaps;
+
+numSnaps = virDomainListAllSnapshots(domains[i], , 0);
+if (numSnaps <= 0)
+continue;
+
+for (gint j = 0; j < numSnaps; j++) {
+gchar *snapPath = 
virtDBusUtilBusPathForVirDomainSnapshot(domains[i],
+  
domainSnapshots[j],
+  
connect->domainSnapshotPath);
+g_ptr_array_add(list, snapPath);
+}
+}
+
+if (list->len > 0)
+g_ptr_array_add(list, NULL);
+
+return (gchar **)g_ptr_array_free(list, FALSE);
+}
+
+static GDBusInterfaceInfo *interfaceInfo = NULL;
+
+void
+virtDBusDomainSnapshotRegister(virtDBusConnect *connect,
+   GError **error)
+{
+connect->domainSnapshotPath = g_strdup_printf("%s/domainsnapshot", 
connect->connectPath);
+
+if (!interfaceInfo) {
+interfaceInfo = 
virtDBusGDBusLoadIntrospectData(VIRT_DBUS_DOMAIN_SNAPSHOT_INTERFACE,
+error);
+if (!interfaceInfo)
+return;
+}
+
+virtDBusGDBusRegisterSubtree(connect->bus,
+ connect->domainSnapshotPath,
+ interfaceInfo,
+ vir

[libvirt] [libvirt-dbus][PATCH v4 2/2] Implement snapshots APIs

2019-11-04 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/org.libvirt.Domain.xml |  26 
 data/org.libvirt.DomainSnapshot.xml |  34 +
 src/domain.c| 154 
 src/domainsnapshot.c| 216 
 tests/libvirttest.py|  12 ++
 tests/meson.build   |   1 +
 tests/test_domain.py|   8 ++
 tests/test_snapshot.py  |  45 ++
 tests/xmldata.py|   6 +
 9 files changed, 502 insertions(+)
 create mode 100755 tests/test_snapshot.py

diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
index b4ed495..3f108e7 100644
--- a/data/org.libvirt.Domain.xml
+++ b/data/org.libvirt.Domain.xml
@@ -350,6 +350,12 @@
   
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainListAllSnapshots"/>
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSave"/>
@@ -589,6 +595,26 @@
 value="See 
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainShutdownFlags"/>
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML"/>
+  
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotLookupByName"/>
+  
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSuspend"/>
diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
index 8ba059f..9e9daac 100644
--- a/data/org.libvirt.DomainSnapshot.xml
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -3,5 +3,39 @@
 
 
   
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotDelete"/>
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetParent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetXMLDesc"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotIsCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListAllChildren"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainRevertToSnapshot"/>
+  
+
   
 
diff --git a/src/domain.c b/src/domain.c
index 10fa8de..a656c6a 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1857,6 +1857,49 @@ virtDBusDomainInjectNMI(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainListDomainSnapshots(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+  gpointer userData,
+  GVariant **outArgs G_GNUC_UNUSED,
+  GUnixFDList **outFDs G_GNUC_UNUSED,
+  GError **error)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomain) domain = NULL;
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+guint flags;
+GVariantBuilder builder;
+GVariant *gdomainSnapshots;
+
+g_variant_get(inArgs, "(u)", );
+
+domain = virtDBusDomainGetVirDomain(connect, objectPath, error);
+if (!domain)
+return;
+
+if (!virtDBusConnectOpen(connect, error))
+return;
+
+if (virDomainListAllSnapshots(domain, , flags) < 0)
+return virtDBusUtilSetLastVirtError(error);
+
+g_variant_builder_init(, G_VARIANT_TYPE("ao"));
+
+for (gint i = 0; domainSnapshots[i]; i++) {
+g_autofree gchar *path = NULL;
+path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
+   domainSnapshots[i],
+   
connect->domainSnapshotPath);
+
+g_variant_builder_add(, "o", path);
+}
+
+gdomainSnapshots = g_variant_builder_end();
+*outArgs = g_variant_new_tuple(, 1);
+}
+
 static void
 virtDBusDomainInterfaceAddresses(GVariant *inArgs,
  GUnixFDList *inFDs G_GNUC_UNUSED,
@@ -2966,6 +3009,113 @@ virtDBusDomainShutdown(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainSnapshotCurrent(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+  gpoi

[libvirt] [libvirt-dbus][PATCH v4 0/2] Implement snapshots

2019-11-04 Thread Simon Kobyda
Changes since v2:
  Implement and use virtDBusDomainSnapshotGetVirDomainSnapshot
  Add domain snapshot xml file to data/meson.build
  Fix flake8 style errors

Simon Kobyda (2):
  Introduce Domain Snapshot Interface
  Implement snapshots APIs

 data/meson.build|   1 +
 data/org.libvirt.Domain.xml |  26 +++
 data/org.libvirt.DomainSnapshot.xml |  41 
 src/connect.c   |   6 +
 src/connect.h   |   1 +
 src/domain.c| 154 +++
 src/domainsnapshot.c| 291 
 src/domainsnapshot.h|   9 +
 src/meson.build |   1 +
 src/util.c  |  53 +
 src/util.h  |  16 ++
 tests/libvirttest.py|  12 ++
 tests/meson.build   |   1 +
 tests/test_domain.py|   8 +
 tests/test_snapshot.py  |  45 +
 tests/xmldata.py|   6 +
 16 files changed, 671 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h
 create mode 100755 tests/test_snapshot.py

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list



[libvirt] [libvirt-dbus][PATCH v3 0/2] Implement snapshots

2019-10-23 Thread Simon Kobyda
Changes since v2:
  Fix underscore in snapshot path
  Use virDomainSnapshotGetDomain instead of own excessive calculations
  Get rid of excessive code in tests
  Appeareance polishes (fix indendation, one-line functions, typos...)

Simon Kobyda (2):
  Introduce Domain Snapshot Interface
  Implement snapshots APIs

 data/org.libvirt.Domain.xml |  26 +++
 data/org.libvirt.DomainSnapshot.xml |  41 +
 src/connect.c   |   6 +
 src/connect.h   |   1 +
 src/domain.c| 154 
 src/domainsnapshot.c| 269 
 src/domainsnapshot.h|   9 +
 src/meson.build |   1 +
 src/util.c  |  53 ++
 src/util.h  |  16 ++
 tests/libvirttest.py|  12 ++
 tests/meson.build   |   1 +
 tests/test_domain.py|   8 +
 tests/test_snapshot.py  |  43 +
 tests/xmldata.py|   6 +
 15 files changed, 646 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h
 create mode 100755 tests/test_snapshot.py

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list



[libvirt] [libvirt-dbus][PATCH v3 2/2] Implement snapshots APIs

2019-10-23 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/org.libvirt.Domain.xml |  26 
 data/org.libvirt.DomainSnapshot.xml |  34 +
 src/domain.c| 154 ++
 src/domainsnapshot.c| 196 +++-
 tests/libvirttest.py|  12 ++
 tests/meson.build   |   1 +
 tests/test_domain.py|   8 ++
 tests/test_snapshot.py  |  43 ++
 tests/xmldata.py|   6 +
 9 files changed, 479 insertions(+), 1 deletion(-)
 create mode 100755 tests/test_snapshot.py

diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
index b4ed495..3f108e7 100644
--- a/data/org.libvirt.Domain.xml
+++ b/data/org.libvirt.Domain.xml
@@ -350,6 +350,12 @@
   
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainListAllSnapshots"/>
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSave"/>
@@ -589,6 +595,26 @@
 value="See 
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainShutdownFlags"/>
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML"/>
+  
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotLookupByName"/>
+  
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSuspend"/>
diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
index 8ba059f..9e9daac 100644
--- a/data/org.libvirt.DomainSnapshot.xml
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -3,5 +3,39 @@
 
 
   
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotDelete"/>
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetParent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetXMLDesc"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotIsCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListAllChildren"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainRevertToSnapshot"/>
+  
+
   
 
diff --git a/src/domain.c b/src/domain.c
index 10fa8de..a656c6a 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1857,6 +1857,49 @@ virtDBusDomainInjectNMI(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainListDomainSnapshots(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+  gpointer userData,
+  GVariant **outArgs G_GNUC_UNUSED,
+  GUnixFDList **outFDs G_GNUC_UNUSED,
+  GError **error)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomain) domain = NULL;
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+guint flags;
+GVariantBuilder builder;
+GVariant *gdomainSnapshots;
+
+g_variant_get(inArgs, "(u)", );
+
+domain = virtDBusDomainGetVirDomain(connect, objectPath, error);
+if (!domain)
+return;
+
+if (!virtDBusConnectOpen(connect, error))
+return;
+
+if (virDomainListAllSnapshots(domain, , flags) < 0)
+return virtDBusUtilSetLastVirtError(error);
+
+g_variant_builder_init(, G_VARIANT_TYPE("ao"));
+
+for (gint i = 0; domainSnapshots[i]; i++) {
+g_autofree gchar *path = NULL;
+path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
+   domainSnapshots[i],
+   
connect->domainSnapshotPath);
+
+g_variant_builder_add(, "o", path);
+}
+
+gdomainSnapshots = g_variant_builder_end();
+*outArgs = g_variant_new_tuple(, 1);
+}
+
 static void
 virtDBusDomainInterfaceAddresses(GVariant *inArgs,
  GUnixFDList *inFDs G_GNUC_UNUSED,
@@ -2966,6 +3009,113 @@ virtDBusDomainShutdown(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainSnapshotCurrent(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+  gpoi

[libvirt] [libvirt-dbus][PATCH v3 1/2] Introduce Domain Snapshot Interface

2019-10-23 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/org.libvirt.DomainSnapshot.xml |  7 +++
 src/connect.c   |  6 +++
 src/connect.h   |  1 +
 src/domainsnapshot.c| 75 +
 src/domainsnapshot.h|  9 
 src/meson.build |  1 +
 src/util.c  | 53 
 src/util.h  | 16 ++
 8 files changed, 168 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h

diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
new file mode 100644
index 000..8ba059f
--- /dev/null
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -0,0 +1,7 @@
+http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd;>
+
+
+  
+  
+
diff --git a/src/connect.c b/src/connect.c
index f8f76a2..b40b0ba 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -1,5 +1,6 @@
 #include "connect.h"
 #include "domain.h"
+#include "domainsnapshot.h"
 #include "events.h"
 #include "interface.h"
 #include "network.h"
@@ -2002,6 +2003,7 @@ virtDBusConnectFree(virtDBusConnect *connect)
 virtDBusConnectClose(connect, TRUE);
 
 g_free(connect->domainPath);
+g_free(connect->domainSnapshotPath);
 g_free(connect->interfacePath);
 g_free(connect->networkPath);
 g_free(connect->nodeDevPath);
@@ -2062,6 +2064,10 @@ virtDBusConnectNew(virtDBusConnect **connectp,
 if (error && *error)
 return;
 
+virtDBusDomainSnapshotRegister(connect, error);
+if (error && *error)
+return;
+
 virtDBusInterfaceRegister(connect, error);
 if (error && *error)
 return;
diff --git a/src/connect.h b/src/connect.h
index 829bd57..74c89cf 100644
--- a/src/connect.h
+++ b/src/connect.h
@@ -13,6 +13,7 @@ struct virtDBusConnect {
 const gchar *uri;
 const gchar *connectPath;
 gchar *domainPath;
+gchar *domainSnapshotPath;
 gchar *interfacePath;
 gchar *networkPath;
 gchar *nodeDevPath;
diff --git a/src/domainsnapshot.c b/src/domainsnapshot.c
new file mode 100644
index 000..c523c9e
--- /dev/null
+++ b/src/domainsnapshot.c
@@ -0,0 +1,75 @@
+#include "domainsnapshot.h"
+#include "util.h"
+
+#include 
+
+static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
+{ 0 }
+};
+
+static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
+{ 0 }
+};
+
+static gchar **
+virtDBusDomainSnapshotEnumerate(gpointer userData)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomainPtr) domains = NULL;
+gint numDoms = 0;
+GPtrArray *list = NULL;
+
+if (!virtDBusConnectOpen(connect, NULL))
+return NULL;
+
+numDoms = virConnectListAllDomains(connect->connection, , 0);
+if (numDoms <= 0)
+return NULL;
+
+list = g_ptr_array_new();
+
+for (gint i = 0; i < numDoms; i++) {
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+gint numSnaps;
+
+numSnaps = virDomainListAllSnapshots(domains[i], , 0);
+if (numSnaps <= 0)
+continue;
+
+for (gint j = 0; j < numSnaps; j++) {
+gchar *snapPath = 
virtDBusUtilBusPathForVirDomainSnapshot(domains[i],
+  
domainSnapshots[j],
+  
connect->domainSnapshotPath);
+g_ptr_array_add(list, snapPath);
+}
+}
+
+if (list->len > 0)
+g_ptr_array_add(list, NULL);
+
+return (gchar **)g_ptr_array_free(list, FALSE);
+}
+
+static GDBusInterfaceInfo *interfaceInfo = NULL;
+
+void
+virtDBusDomainSnapshotRegister(virtDBusConnect *connect,
+   GError **error)
+{
+connect->domainSnapshotPath = g_strdup_printf("%s/domainsnapshot", 
connect->connectPath);
+
+if (!interfaceInfo) {
+interfaceInfo = 
virtDBusGDBusLoadIntrospectData(VIRT_DBUS_DOMAIN_SNAPSHOT_INTERFACE,
+error);
+if (!interfaceInfo)
+return;
+}
+
+virtDBusGDBusRegisterSubtree(connect->bus,
+ connect->domainSnapshotPath,
+ interfaceInfo,
+ virtDBusDomainSnapshotEnumerate,
+ virtDBusDomainSnapshotMethodTable,
+ virtDBusDomainSnapshotPropertyTable,
+ connect);
+}
diff --git a/src/domainsnapshot.h b/src/domainsnapshot.h
new file mode 100644
index 000..7d8a938
--- /dev/null
+++ b/src/domainsnapshot.h
@@ -0,0 +1,9 @@
+#pragma o

[libvirt] [libvirt-dbus] [PATCH 0/2] Implement snapshots

2019-10-10 Thread Simon Kobyda
Implement snapshot interface and its APIs.

Simon Kobyda (2):
  Introduce Domain Snapshot Interface
  Implement snapshots APIs

 data/org.libvirt.Domain.xml |  26 +++
 data/org.libvirt.DomainSnapshot.xml |  41 
 src/connect.c   |   6 +
 src/connect.h   |   1 +
 src/domain.c| 158 
 src/domainsnapshot.c| 282 
 src/domainsnapshot.h|   9 +
 src/meson.build |   1 +
 src/util.c  |  49 +
 src/util.h  |  16 ++
 tests/libvirttest.py|  14 ++
 tests/meson.build   |   1 +
 tests/test_domain.py|   8 +
 tests/test_snapshot.py  |  43 +
 tests/xmldata.py|   6 +
 15 files changed, 661 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h
 create mode 100755 tests/test_snapshot.py

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [libvirt-dbus] [PATCH 2/2] Implement snapshots APIs

2019-10-10 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/org.libvirt.Domain.xml |  26 
 data/org.libvirt.DomainSnapshot.xml |  34 +
 src/domain.c| 158 +
 src/domainsnapshot.c| 205 +++-
 tests/libvirttest.py|  14 ++
 tests/meson.build   |   1 +
 tests/test_domain.py|   8 ++
 tests/test_snapshot.py  |  43 ++
 tests/xmldata.py|   6 +
 9 files changed, 494 insertions(+), 1 deletion(-)
 create mode 100755 tests/test_snapshot.py

diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
index b4ed495..f03faf8 100644
--- a/data/org.libvirt.Domain.xml
+++ b/data/org.libvirt.Domain.xml
@@ -350,6 +350,12 @@
   
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainListAllSnapshots"/>
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSave"/>
@@ -589,6 +595,26 @@
 value="See 
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainShutdownFlags"/>
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML"/>
+  
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotLookupByName"/>
+  
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSuspend"/>
diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
index 80f61c6..463654f 100644
--- a/data/org.libvirt.DomainSnapshot.xml
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -3,5 +3,39 @@
 
 
   
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotDelete"/>
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetParent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetXMLDesc"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotIsCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListAllChildren"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainRevertToSnapshot"/>
+  
+
   
 
diff --git a/src/domain.c b/src/domain.c
index 10fa8de..3fc5bab 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1857,6 +1857,50 @@ virtDBusDomainInjectNMI(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainListDomainSnapshots(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+  gpointer userData,
+  GVariant **outArgs G_GNUC_UNUSED,
+  GUnixFDList **outFDs G_GNUC_UNUSED,
+  GError **error)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomain) domain = NULL;
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+guint flags;
+GVariantBuilder builder;
+GVariant *gdomainSnapshots;
+
+g_variant_get(inArgs, "(u)", );
+
+domain = virtDBusDomainGetVirDomain(connect, objectPath,
+error);
+if (!domain)
+return;
+
+if (!virtDBusConnectOpen(connect, error))
+return;
+
+if (virDomainListAllSnapshots(domain, , flags) < 0)
+return virtDBusUtilSetLastVirtError(error);
+
+g_variant_builder_init(, G_VARIANT_TYPE("ao"));
+
+for (gint i = 0; domainSnapshots[i]; i++) {
+g_autofree gchar *path = NULL;
+path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
+   domainSnapshots[i],
+   
connect->domainSnapshotPath);
+
+g_variant_builder_add(, "o", path);
+}
+
+gdomainSnapshots = g_variant_builder_end();
+*outArgs = g_variant_new_tuple(, 1);
+}
+
 static void
 virtDBusDomainInterfaceAddresses(GVariant *inArgs,
  GUnixFDList *inFDs G_GNUC_UNUSED,
@@ -2966,6 +3010,116 @@ virtDBusDomainShutdown(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainSnapshotCurrent(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+   

[libvirt] [libvirt-dbus] [PATCH 1/2] Introduce Domain Snapshot Interface

2019-10-10 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/org.libvirt.DomainSnapshot.xml |  7 +++
 src/connect.c   |  6 +++
 src/connect.h   |  1 +
 src/domainsnapshot.c| 79 +
 src/domainsnapshot.h|  9 
 src/meson.build |  1 +
 src/util.c  | 49 ++
 src/util.h  | 16 ++
 8 files changed, 168 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h

diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
new file mode 100644
index 000..80f61c6
--- /dev/null
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -0,0 +1,7 @@
+http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd;>
+
+
+  
+  
+
diff --git a/src/connect.c b/src/connect.c
index f8f76a2..b40b0ba 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -1,5 +1,6 @@
 #include "connect.h"
 #include "domain.h"
+#include "domainsnapshot.h"
 #include "events.h"
 #include "interface.h"
 #include "network.h"
@@ -2002,6 +2003,7 @@ virtDBusConnectFree(virtDBusConnect *connect)
 virtDBusConnectClose(connect, TRUE);
 
 g_free(connect->domainPath);
+g_free(connect->domainSnapshotPath);
 g_free(connect->interfacePath);
 g_free(connect->networkPath);
 g_free(connect->nodeDevPath);
@@ -2062,6 +2064,10 @@ virtDBusConnectNew(virtDBusConnect **connectp,
 if (error && *error)
 return;
 
+virtDBusDomainSnapshotRegister(connect, error);
+if (error && *error)
+return;
+
 virtDBusInterfaceRegister(connect, error);
 if (error && *error)
 return;
diff --git a/src/connect.h b/src/connect.h
index 829bd57..74c89cf 100644
--- a/src/connect.h
+++ b/src/connect.h
@@ -13,6 +13,7 @@ struct virtDBusConnect {
 const gchar *uri;
 const gchar *connectPath;
 gchar *domainPath;
+gchar *domainSnapshotPath;
 gchar *interfacePath;
 gchar *networkPath;
 gchar *nodeDevPath;
diff --git a/src/domainsnapshot.c b/src/domainsnapshot.c
new file mode 100644
index 000..590cbef
--- /dev/null
+++ b/src/domainsnapshot.c
@@ -0,0 +1,79 @@
+#include "domainsnapshot.h"
+#include "util.h"
+
+#include 
+
+static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
+{ 0 }
+};
+
+static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
+{ 0 }
+};
+
+static gchar **
+virtDBusDomainSnapshotEnumerate(gpointer userData)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomainPtr) domains = NULL;
+gint numDoms = 0;
+GPtrArray *list = NULL;
+
+if (!virtDBusConnectOpen(connect, NULL))
+return NULL;
+
+numDoms = virConnectListAllDomains(connect->connection, , 0);
+if (numDoms <= 0)
+return NULL;
+
+list = g_ptr_array_new();
+
+for (gint i = 0; i < numDoms; i++) {
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+gint numSnaps;
+
+numSnaps = virDomainListAllSnapshots(domains[i], , 0);
+if (numSnaps <= 0)
+continue;
+
+for (gint j = 0; j < numSnaps; j++) {
+gchar *snapPath = 
virtDBusUtilBusPathForVirDomainSnapshot(domains[i],
+  
domainSnapshots[j],
+  
connect->domainSnapshotPath);
+g_ptr_array_add(list, snapPath);
+}
+}
+
+gchar **ret = g_new0(gchar *, numDoms + 1);
+
+for (gint i = 0; i < numDoms; i++) {
+ret[i] = virtDBusUtilBusPathForVirDomain(domains[i],
+ connect->domainPath);
+}
+
+return ret;
+}
+
+static GDBusInterfaceInfo *interfaceInfo = NULL;
+
+void
+virtDBusDomainSnapshotRegister(virtDBusConnect *connect,
+   GError **error)
+{
+connect->domainSnapshotPath = g_strdup_printf("%s/snapshot", 
connect->connectPath);
+
+if (!interfaceInfo) {
+interfaceInfo = 
virtDBusGDBusLoadIntrospectData(VIRT_DBUS_DOMAIN_SNAPSHOT_INTERFACE,
+error);
+if (!interfaceInfo)
+return;
+}
+
+virtDBusGDBusRegisterSubtree(connect->bus,
+ connect->domainSnapshotPath,
+ interfaceInfo,
+ virtDBusDomainSnapshotEnumerate,
+ virtDBusDomainSnapshotMethodTable,
+ virtDBusDomainSnapshotPropertyTable,
+ connect);
+}
diff --git a/src/domainsnapshot.h b/sr

[libvirt] [libvirt-dbus] [PATCH 1/2] Introduce Domain Snapshot Interface

2019-10-07 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/Makefile.am|  1 +
 data/org.libvirt.DomainSnapshot.xml |  7 +++
 src/Makefile.am |  2 +
 src/connect.c   |  6 +++
 src/connect.h   |  1 +
 src/domainsnapshot.c| 79 +
 src/domainsnapshot.h|  9 
 src/util.c  | 47 +
 src/util.h  | 16 ++
 9 files changed, 168 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h

diff --git a/data/Makefile.am b/data/Makefile.am
index f8311bd..5617c78 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -33,6 +33,7 @@ polkit_DATA = \
 interfaces_files = \
org.libvirt.Connect.xml \
org.libvirt.Domain.xml \
+   org.libvirt.DomainSnapshot.xml \
org.libvirt.Interface.xml \
org.libvirt.Network.xml \
org.libvirt.NodeDevice.xml \
diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
new file mode 100644
index 000..80f61c6
--- /dev/null
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -0,0 +1,7 @@
+http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd;>
+
+
+  
+  
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 845696e..a78bac8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,8 @@ libvirt_dbus_SOURCES = \
connect.h \
domain.c \
domain.h \
+   domainsnapshot.c \
+   domainsnapshot.h \
events.c \
events.h \
gdbus.c \
diff --git a/src/connect.c b/src/connect.c
index f8f76a2..b40b0ba 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -1,5 +1,6 @@
 #include "connect.h"
 #include "domain.h"
+#include "domainsnapshot.h"
 #include "events.h"
 #include "interface.h"
 #include "network.h"
@@ -2002,6 +2003,7 @@ virtDBusConnectFree(virtDBusConnect *connect)
 virtDBusConnectClose(connect, TRUE);
 
 g_free(connect->domainPath);
+g_free(connect->domainSnapshotPath);
 g_free(connect->interfacePath);
 g_free(connect->networkPath);
 g_free(connect->nodeDevPath);
@@ -2062,6 +2064,10 @@ virtDBusConnectNew(virtDBusConnect **connectp,
 if (error && *error)
 return;
 
+virtDBusDomainSnapshotRegister(connect, error);
+if (error && *error)
+return;
+
 virtDBusInterfaceRegister(connect, error);
 if (error && *error)
 return;
diff --git a/src/connect.h b/src/connect.h
index 829bd57..74c89cf 100644
--- a/src/connect.h
+++ b/src/connect.h
@@ -13,6 +13,7 @@ struct virtDBusConnect {
 const gchar *uri;
 const gchar *connectPath;
 gchar *domainPath;
+gchar *domainSnapshotPath;
 gchar *interfacePath;
 gchar *networkPath;
 gchar *nodeDevPath;
diff --git a/src/domainsnapshot.c b/src/domainsnapshot.c
new file mode 100644
index 000..590cbef
--- /dev/null
+++ b/src/domainsnapshot.c
@@ -0,0 +1,79 @@
+#include "domainsnapshot.h"
+#include "util.h"
+
+#include 
+
+static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
+{ 0 }
+};
+
+static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
+{ 0 }
+};
+
+static gchar **
+virtDBusDomainSnapshotEnumerate(gpointer userData)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomainPtr) domains = NULL;
+gint numDoms = 0;
+GPtrArray *list = NULL;
+
+if (!virtDBusConnectOpen(connect, NULL))
+return NULL;
+
+numDoms = virConnectListAllDomains(connect->connection, , 0);
+if (numDoms <= 0)
+return NULL;
+
+list = g_ptr_array_new();
+
+for (gint i = 0; i < numDoms; i++) {
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+gint numSnaps;
+
+numSnaps = virDomainListAllSnapshots(domains[i], , 0);
+if (numSnaps <= 0)
+continue;
+
+for (gint j = 0; j < numSnaps; j++) {
+gchar *snapPath = 
virtDBusUtilBusPathForVirDomainSnapshot(domains[i],
+  
domainSnapshots[j],
+  
connect->domainSnapshotPath);
+g_ptr_array_add(list, snapPath);
+}
+}
+
+gchar **ret = g_new0(gchar *, numDoms + 1);
+
+for (gint i = 0; i < numDoms; i++) {
+ret[i] = virtDBusUtilBusPathForVirDomain(domains[i],
+ connect->domainPath);
+}
+
+return ret;
+}
+
+static GDBusInterfaceInfo *interfaceInfo = NULL;
+
+void
+virtDBusDomainSnapshotRegister(virtDBusConnect *connect,
+   GError **error)
+{
+connect->domainSnapshotPath = g_strdup_printf("%s/sna

[libvirt] [libvirt-dbus] [PATCH 0/2] Implement Snaphots

2019-10-07 Thread Simon Kobyda
Implement snapshot interface and its APIs.

Simon Kobyda (2):
  Introduce Domain Snapshot Interface
  Implement snapshots APIs

 data/Makefile.am|   1 +
 data/org.libvirt.Domain.xml |  26 +++
 data/org.libvirt.DomainSnapshot.xml |  41 
 src/Makefile.am |   2 +
 src/connect.c   |   6 +
 src/connect.h   |   1 +
 src/domain.c| 158 
 src/domainsnapshot.c| 281 
 src/domainsnapshot.h|   9 +
 src/util.c  |  47 +
 src/util.h  |  16 ++
 tests/Makefile.am   |   1 +
 tests/libvirttest.py|  14 ++
 tests/test_domain.py|   8 +
 tests/test_snapshot.py  |  43 +
 tests/xmldata.py|   6 +
 16 files changed, 660 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h
 create mode 100755 tests/test_snapshot.py

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [libvirt-dbus] [PATCH 2/2] Implement snapshots APIs

2019-10-07 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 data/org.libvirt.Domain.xml |  26 
 data/org.libvirt.DomainSnapshot.xml |  34 +
 src/domain.c| 158 +
 src/domainsnapshot.c| 204 +++-
 tests/Makefile.am   |   1 +
 tests/libvirttest.py|  14 ++
 tests/test_domain.py|   8 ++
 tests/test_snapshot.py  |  43 ++
 tests/xmldata.py|   6 +
 9 files changed, 493 insertions(+), 1 deletion(-)
 create mode 100755 tests/test_snapshot.py

diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
index b4ed495..f03faf8 100644
--- a/data/org.libvirt.Domain.xml
+++ b/data/org.libvirt.Domain.xml
@@ -350,6 +350,12 @@
   
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainListAllSnapshots"/>
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSave"/>
@@ -589,6 +595,26 @@
 value="See 
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainShutdownFlags"/>
   
 
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML"/>
+  
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotLookupByName"/>
+  
+  
+  
+
 
   https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSuspend"/>
diff --git a/data/org.libvirt.DomainSnapshot.xml 
b/data/org.libvirt.DomainSnapshot.xml
index 80f61c6..463654f 100644
--- a/data/org.libvirt.DomainSnapshot.xml
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -3,5 +3,39 @@
 
 
   
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotDelete"/>
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetParent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetXMLDesc"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotIsCurrent"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListAllChildren"/>
+  
+  
+
+
+  https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainRevertToSnapshot"/>
+  
+
   
 
diff --git a/src/domain.c b/src/domain.c
index 10fa8de..3fc5bab 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1857,6 +1857,50 @@ virtDBusDomainInjectNMI(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainListDomainSnapshots(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+  gpointer userData,
+  GVariant **outArgs G_GNUC_UNUSED,
+  GUnixFDList **outFDs G_GNUC_UNUSED,
+  GError **error)
+{
+virtDBusConnect *connect = userData;
+g_autoptr(virDomain) domain = NULL;
+g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+guint flags;
+GVariantBuilder builder;
+GVariant *gdomainSnapshots;
+
+g_variant_get(inArgs, "(u)", );
+
+domain = virtDBusDomainGetVirDomain(connect, objectPath,
+error);
+if (!domain)
+return;
+
+if (!virtDBusConnectOpen(connect, error))
+return;
+
+if (virDomainListAllSnapshots(domain, , flags) < 0)
+return virtDBusUtilSetLastVirtError(error);
+
+g_variant_builder_init(, G_VARIANT_TYPE("ao"));
+
+for (gint i = 0; domainSnapshots[i]; i++) {
+g_autofree gchar *path = NULL;
+path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
+   domainSnapshots[i],
+   
connect->domainSnapshotPath);
+
+g_variant_builder_add(, "o", path);
+}
+
+gdomainSnapshots = g_variant_builder_end();
+*outArgs = g_variant_new_tuple(, 1);
+}
+
 static void
 virtDBusDomainInterfaceAddresses(GVariant *inArgs,
  GUnixFDList *inFDs G_GNUC_UNUSED,
@@ -2966,6 +3010,116 @@ virtDBusDomainShutdown(GVariant *inArgs,
 virtDBusUtilSetLastVirtError(error);
 }
 
+static void
+virtDBusDomainSnapshotCurrent(GVariant *inArgs,
+  GUnixFDList *inFDs G_GNUC_UNUSED,
+  const gchar *objectPath,
+   

[libvirt] [PATCH 0/2] vsh-table: Remove trailing spaces

2018-11-27 Thread Simon Kobyda
Right now, each line in last column of our table leaves trailing spaces.
Let's get rid of it.

Simon Kobyda (2):
  vsh-table: Get rid of trailing spaces
  tests: Remove trailing spaces in test cases

 tests/virshtest.c| 10 
 tests/vshtabletest.c | 58 ++--
 tools/vsh-table.c|  6 +++--
 3 files changed, 38 insertions(+), 36 deletions(-)

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 2/2] tests: Remove trailing spaces in test cases

2018-11-27 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tests/virshtest.c| 10 
 tests/vshtabletest.c | 58 ++--
 2 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/tests/virshtest.c b/tests/virshtest.c
index 250efb7734..7fb701d580 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -96,9 +96,9 @@ static int testCompareListDefault(const void *data 
ATTRIBUTE_UNUSED)
 {
 const char *const argv[] = { VIRSH_DEFAULT, "list", NULL };
 const char *exp = "\
- Id   Name   State\n\
+ Id   Name   State\n\
 --\n\
- 1test   running  \n\
+ 1test   running\n\
 \n";
 return testCompareOutputLit(exp, NULL, argv);
 }
@@ -107,10 +107,10 @@ static int testCompareListCustom(const void *data 
ATTRIBUTE_UNUSED)
 {
 const char *const argv[] = { VIRSH_CUSTOM, "list", NULL };
 const char *exp = "\
- Id   Name   State\n\
+ Id   Name   State\n\
 --\n\
- 1fv0running  \n\
- 2fc4running  \n\
+ 1fv0running\n\
+ 2fc4running\n\
 \n";
 return testCompareOutputLit(exp, NULL, argv);
 }
diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
index ff394f65ca..e795c5afc0 100644
--- a/tests/vshtabletest.c
+++ b/tests/vshtabletest.c
@@ -43,13 +43,13 @@ testVshTableHeader(const void *opaque ATTRIBUTE_UNUSED)
 int ret = 0;
 char *act = NULL;
 const char *exp =
-" 1   fedora28   running  \n"
-" 2   rhel7.5running  \n";
+" 1   fedora28   running\n"
+" 2   rhel7.5running\n";
 const char *exp2 =
-" Id   Name   State\n"
+" Id   Name   State\n"
 "--\n"
-" 1fedora28   running  \n"
-" 2rhel7.5running  \n";
+" 1fedora28   running\n"
+" 2rhel7.5running\n";
 
 vshTablePtr table = vshTableNew("Id", "Name", "State",
 NULL); //to ask about return
@@ -118,10 +118,10 @@ testUnicode(const void *opaque ATTRIBUTE_UNUSED)
 char *act = NULL;
 
 const char *exp =
-" Id   名稱  государство  \n"
+" Id   名稱  государство\n"
 "-\n"
-" 1fedora28  running  \n"
-" 2つへソrhel7.5つへソ   running  \n";
+" 1fedora28  running\n"
+" 2つへソrhel7.5つへソ   running\n";
 vshTablePtr table;
 
 table = vshTableNew("Id", "名稱", "государство", NULL);
@@ -150,10 +150,10 @@ testUnicodeArabic(const void *opaque ATTRIBUTE_UNUSED)
 char *act = NULL;
 
 const char *exp =
-" ﻡﺍ ﻢﻣﺍ ﻕﺎﺌﻣﺓ   ﺓ ﺎﻠﺼﻋ ﺍﻸﺜﻧﺎﻧ 
 \n"
+" ﻡﺍ ﻢﻣﺍ ﻕﺎﺌﻣﺓ   ﺓ ﺎﻠﺼﻋ 
ﺍﻸﺜﻧﺎﻧ\n"
 
"---\n"
-" 1  ﻉﺪﻴﻟ ﺎﻠﺜﻘﻴﻟ ﻕﺎﻣ ﻊﻧ, ٣٠ ﻎﻴﻨﻳﺍ ﻮﺘﻧﺎﻤﺗ ﺎﻠﺛﺎﻠﺛ، ﺄﺳﺭ, ﺩﻮﻟ   ﺩﻮﻟ. 
ﺄﻣﺎﻣ ﺍ ﺎﻧ ﻲﻜﻧ  \n"
-" ﺺﻔﺣﺓ   ﺖﻜﺘﻴﻛﺍً ﻊﻟ, ﺎﻠﺠﻧﻭﺩ ﻭﺎﻠﻌﺗﺍﺩ  ﺵﺭ
  \n";
+" 1  ﻉﺪﻴﻟ ﺎﻠﺜﻘﻴﻟ ﻕﺎﻣ ﻊﻧ, ٣٠ ﻎﻴﻨﻳﺍ ﻮﺘﻧﺎﻤﺗ ﺎﻠﺛﺎﻠﺛ، ﺄﺳﺭ, ﺩﻮﻟ   ﺩﻮﻟ. 
ﺄﻣﺎﻣ ﺍ ﺎﻧ ﻲﻜﻧ\n"
+" ﺺﻔﺣﺓ   ﺖﻜﺘﻴﻛﺍً ﻊﻟ, ﺎﻠﺠﻧﻭﺩ ﻭﺎﻠﻌﺗﺍﺩ  ﺵﺭ\n";
 vshTablePtr table;
 wchar_t wc;
 
@@ -192,10 +192,10 @@ testUnicodeZeroWidthChar(const void *opaque 
ATTRIBUTE_UNUSED)
 int ret = 0;
 vshTablePtr table = NULL;
 const char *exp =
-" I\u200Bd   Name   \u200BStatus   \n"
+" I\u200Bd   Name   \u200BStatus\n"
 "--\n"
-" 1\u200Bfedora28   run\u200Bning  \n"
-" 2rhel7.5running  \n";
+" 1\u200Bfedora28   run\u200Bning\n"
+" 2rhel7.5running\n";
 char *act = NULL;
 wchar_t wc;
 
@@ -229,10 +229,10 @@ testUnicodeCombiningChar(const void *opaque 
ATTRIBUTE_UNUSED)
 int ret = 0;
 vshTablePtr table = NULL;
 const char *exp =
-" Id   Náme   Ⓢtatus   \n"
+" Id   Náme   Ⓢtatus\n"
 "--\n"
-" 1fědora28   running  \n"
-" 2rhel   running  \n";
+" 1fědora28   running\n"
+" 2rhel   running\n";
 char *act = NULL;
 
 table = vshTableNew("Id", "Náme", "Ⓢtatus", NULL);
@@ -258,10 +258,10 @@ testUnicodeNonPrintableChar(const void *opaque 
ATTRIBUTE_UNUSED)
 int ret = 0;
 vshTablePtr table = NULL;
 const char *exp =
-" I\\x09d   Name   Status   \n"
+" I\\x09d   Name   Status\n"
 "--\n"
-" 1 

[libvirt] [PATCH 1/2] vsh-table: Get rid of trailing spaces

2018-11-27 Thread Simon Kobyda
Get rid of trailing spaces which can be found after last column in tables.

Signed-off-by: Simon Kobyda 
---
 tools/vsh-table.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/vsh-table.c b/tools/vsh-table.c
index 9b4a34c1e6..fb656ffeb0 100644
--- a/tools/vsh-table.c
+++ b/tools/vsh-table.c
@@ -348,8 +348,10 @@ vshTableRowPrint(vshTableRowPtr row,
 for (i = 0; i < row->ncells; i++) {
 virBufferAsprintf(buf, " %s", row->cells[i]);
 
-for (j = 0; j < maxwidths[i] - widths[i] + 2; j++)
-virBufferAddChar(buf, ' ');
+if (i < (row->ncells - 1)) {
+for (j = 0; j < maxwidths[i] - widths[i] + 2; j++)
+virBufferAddChar(buf, ' ');
+}
 }
 virBufferAddChar(buf, '\n');
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 09/13] virsh: Implement vshTable API to domiflist

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 41 ++--
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b887bb48d9..4bba8438af 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -693,6 +693,7 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 int ninterfaces;
 xmlNodePtr *interfaces = NULL;
 size_t i;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "inactive"))
 flags |= VIR_DOMAIN_XML_INACTIVE;
@@ -704,16 +705,17 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 if (ninterfaces < 0)
 goto cleanup;
 
-vshPrintExtra(ctl, "%-10s %-10s %-10s %-11s %s\n", _("Interface"),
-  _("Type"), _("Source"), _("Model"), _("MAC"));
-vshPrintExtra(ctl, 
"---\n");
+table = vshTableNew(_("Interface"), _("Type"),
+_("Source"), _("Model"), _("MAC"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < ninterfaces; i++) {
-char *type = NULL;
-char *source = NULL;
-char *target = NULL;
-char *model = NULL;
-char *mac = NULL;
+VIR_AUTOFREE(char *) type = NULL;
+VIR_AUTOFREE(char *) source = NULL;
+VIR_AUTOFREE(char *) target = NULL;
+VIR_AUTOFREE(char *) model = NULL;
+VIR_AUTOFREE(char *) mac = NULL;
 
 ctxt->node = interfaces[i];
 type = virXPathString("string(./@type)", ctxt);
@@ -727,23 +729,22 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 model = virXPathString("string(./model/@type)", ctxt);
 mac = virXPathString("string(./mac/@address)", ctxt);
 
-vshPrint(ctl, "%-10s %-10s %-10s %-11s %-10s\n",
- target ? target : "-",
- type,
- source ? source : "-",
- model ? model : "-",
- mac ? mac : "-");
-
-VIR_FREE(type);
-VIR_FREE(source);
-VIR_FREE(target);
-VIR_FREE(model);
-VIR_FREE(mac);
+if (vshTableRowAppend(table,
+  target ? target : "-",
+  type,
+  source ? source : "-",
+  model ? model : "-",
+  mac ? mac : "-",
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 VIR_FREE(interfaces);
 xmlFreeDoc(xmldoc);
 xmlXPathFreeContext(ctxt);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 11/13] virsh: Implement vshTable API to pool-list

2018-09-21 Thread Simon Kobyda
Local lengthy unicode-unreliable table formatting was replaced by new
API. Great example of how new API saves space and time.
Removed a lot of string lenght canculation used by the local table.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-pool.c | 162 +
 1 file changed, 31 insertions(+), 131 deletions(-)

diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index 89206a48f5..75ec572af2 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -33,6 +33,7 @@
 #include "conf/storage_conf.h"
 #include "virstring.h"
 #include "virtime.h"
+#include "vsh-table.h"
 
 #define VIRSH_COMMON_OPT_POOL_FULL(cflags) \
 VIRSH_COMMON_OPT_POOL(N_("pool name or uuid"), cflags)
@@ -1113,10 +1114,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 virStoragePoolInfo info;
 size_t i;
 bool ret = false;
-size_t stringLength = 0, nameStrLength = 0;
-size_t autostartStrLength = 0, persistStrLength = 0;
-size_t stateStrLength = 0, capStrLength = 0;
-size_t allocStrLength = 0, availStrLength = 0;
 struct poolInfoText {
 char *state;
 char *autostart;
@@ -1133,7 +1130,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 bool inactive, all;
 bool uuid = false;
 bool name = false;
-char *outputStr = NULL;
+vshTablePtr table = NULL;
 
 inactive = vshCommandOptBool(cmd, "inactive");
 all = vshCommandOptBool(cmd, "all");
@@ -1260,11 +1257,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 else
 poolInfoTexts[i].persistent = vshStrdup(ctl, persistent ?
  _("yes") : _("no"));
-
-/* Keep the length of persistent string if longest so far */
-stringLength = strlen(poolInfoTexts[i].persistent);
-if (stringLength > persistStrLength)
-persistStrLength = stringLength;
 }
 
 /* Collect further extended information about the pool */
@@ -1310,21 +1302,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 poolInfoTexts[i].allocation = vshStrdup(ctl, _("-"));
 poolInfoTexts[i].available = vshStrdup(ctl, _("-"));
 }
-
-/* Keep the length of capacity string if longest so far */
-stringLength = strlen(poolInfoTexts[i].capacity);
-if (stringLength > capStrLength)
-capStrLength = stringLength;
-
-/* Keep the length of allocation string if longest so far */
-stringLength = strlen(poolInfoTexts[i].allocation);
-if (stringLength > allocStrLength)
-allocStrLength = stringLength;
-
-/* Keep the length of available string if longest so far */
-stringLength = strlen(poolInfoTexts[i].available);
-if (stringLength > availStrLength)
-availStrLength = stringLength;
 } else {
 /* --details option was not specified, only active/inactive
  * state strings are used */
@@ -1334,21 +1311,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 poolInfoTexts[i].state = vshStrdup(ctl, _("inactive"));
}
 }
-
-/* Keep the length of name string if longest so far */
-stringLength = strlen(virStoragePoolGetName(list->pools[i]));
-if (stringLength > nameStrLength)
-nameStrLength = stringLength;
-
-/* Keep the length of state string if longest so far */
-stringLength = strlen(poolInfoTexts[i].state);
-if (stringLength > stateStrLength)
-stateStrLength = stringLength;
-
-/* Keep the length of autostart string if longest so far */
-stringLength = strlen(poolInfoTexts[i].autostart);
-if (stringLength > autostartStrLength)
-autostartStrLength = stringLength;
 }
 
 /* If the --details option wasn't selected, we output the pool
@@ -1376,19 +1338,23 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 }
 
 /* Output old style header */
-vshPrintExtra(ctl, " %-20s %-10s %-10s\n", _("Name"), _("State"),
-  _("Autostart"));
-vshPrintExtra(ctl, "---\n");
+table = vshTableNew(_("Name"), _("State"), _("Autostart"), NULL);
+if (!table)
+goto cleanup;
 
 /* Output old style pool info */
 for (i = 0; i < list->npools; i++) {
 const char *name_str = virStoragePoolGet

[libvirt] [PATCH v2 08/13] virsh: Implement vshTable API to domblklist

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 80c7e8a99e..b887bb48d9 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -589,6 +589,7 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 char *device = NULL;
 char *target = NULL;
 char *source = NULL;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "inactive"))
 flags |= VIR_DOMAIN_XML_INACTIVE;
@@ -603,12 +604,12 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 
 if (details)
-vshPrintExtra(ctl, "%-10s %-10s %-10s %s\n", _("Type"),
-  _("Device"), _("Target"), _("Source"));
+table = vshTableNew(_("Type"), _("Device"), _("Target"), _("Source"), 
NULL);
 else
-vshPrintExtra(ctl, "%-10s %s\n", _("Target"), _("Source"));
+table = vshTableNew(_("Target"), _("Source"), NULL);
 
-vshPrintExtra(ctl, "\n");
+if (!table)
+goto cleanup;
 
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
@@ -633,10 +634,13 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 "|./source/@name"
 "|./source/@volume)", ctxt);
 if (details) {
-vshPrint(ctl, "%-10s %-10s %-10s %s\n", type, device,
- target, source ? source : "-");
+if (vshTableRowAppend(table, type, device, target,
+  source ? source : "-", NULL) < 0)
+goto cleanup;
 } else {
-vshPrint(ctl, "%-10s %s\n", target, source ? source : "-");
+if (vshTableRowAppend(table, target,
+  source ? source : "-", NULL) < 0)
+goto cleanup;
 }
 
 VIR_FREE(source);
@@ -645,9 +649,12 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 VIR_FREE(type);
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 VIR_FREE(source);
 VIR_FREE(target);
 VIR_FREE(device);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 12/13] virsh: Implement vshTable API to vol-list

2018-09-21 Thread Simon Kobyda
Local lengthy unicode-unreliable table formatting was replaced by new
API. Great example of how new API saves space and time.
Removed a lot of string lenght calculation used by the local table.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-volume.c | 129 ++-
 1 file changed, 28 insertions(+), 101 deletions(-)

diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 42d11701ec..6cd989446e 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -42,6 +42,7 @@
 #include "virsh-pool.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 #define VIRSH_COMMON_OPT_POOL_FULL \
 VIRSH_COMMON_OPT_POOL(N_("pool name or uuid"), \
@@ -1382,16 +1383,11 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 {
 virStorageVolInfo volumeInfo;
 virStoragePoolPtr pool;
-char *outputStr = NULL;
 const char *unit;
 double val;
 bool details = vshCommandOptBool(cmd, "details");
 size_t i;
 bool ret = false;
-int stringLength = 0;
-size_t allocStrLength = 0, capStrLength = 0;
-size_t nameStrLength = 0, pathStrLength = 0;
-size_t typeStrLength = 0;
 struct volInfoText {
 char *allocation;
 char *capacity;
@@ -1400,6 +1396,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 };
 struct volInfoText *volInfoTexts = NULL;
 virshStorageVolListPtr list = NULL;
+vshTablePtr table = NULL;
 
 /* Look up the pool information given to us by the user */
 if (!(pool = virshCommandOptPool(ctl, cmd, "pool", NULL)))
@@ -1446,36 +1443,6 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 "%.2lf %s", val, unit) < 0)
 goto cleanup;
 }
-
-/* Remember the largest length for each output string.
- * This lets us displaying header and volume information rows
- * using a single, properly sized, printf style output string.
- */
-
-/* Keep the length of name string if longest so far */
-stringLength = strlen(virStorageVolGetName(list->vols[i]));
-if (stringLength > nameStrLength)
-nameStrLength = stringLength;
-
-/* Keep the length of path string if longest so far */
-stringLength = strlen(volInfoTexts[i].path);
-if (stringLength > pathStrLength)
-pathStrLength = stringLength;
-
-/* Keep the length of type string if longest so far */
-stringLength = strlen(volInfoTexts[i].type);
-if (stringLength > typeStrLength)
-typeStrLength = stringLength;
-
-/* Keep the length of capacity string if longest so far */
-stringLength = strlen(volInfoTexts[i].capacity);
-if (stringLength > capStrLength)
-capStrLength = stringLength;
-
-/* Keep the length of allocation string if longest so far */
-stringLength = strlen(volInfoTexts[i].allocation);
-if (stringLength > allocStrLength)
-allocStrLength = stringLength;
 }
 }
 
@@ -1487,14 +1454,20 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 /* Output basic info then return if --details option not selected */
 if (!details) {
 /* The old output format */
-vshPrintExtra(ctl, " %-20s %-40s\n", _("Name"), _("Path"));
-vshPrintExtra(ctl, "---"
-   "---\n");
+table = vshTableNew(_("Name"), _("Path"), NULL);
+if (!table)
+goto cleanup;
+
 for (i = 0; i < list->nvols; i++) {
-vshPrint(ctl, " %-20s %-40s\n", 
virStorageVolGetName(list->vols[i]),
- volInfoTexts[i].path);
+if (vshTableRowAppend(table,
+  virStorageVolGetName(list->vols[i]),
+  volInfoTexts[i].path,
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
 /* Cleanup and return */
 ret = true;
 goto cleanup;
@@ -1502,75 +1475,30 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 
 /* We only get here if the --details option was selected. */
 
-/* Use the length of name header string if it's longest */
-stringLength = strlen(_("Name"));
-if (stringLength > nameStrLength)
-nameStrLength = stringLength;
-
-/* Use the length of path header string if it's longest */
-stringLength = strlen(_("Path"));
-if (stringLength >

[libvirt] [PATCH v2 02/13] virsh: Implement vshTable API to net-list and net-dhcp-leases

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-network.c | 59 ---
 1 file changed, 38 insertions(+), 21 deletions(-)

diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index ca07fb568f..440b23d8a8 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -33,6 +33,7 @@
 #include "virstring.h"
 #include "virtime.h"
 #include "conf/network_conf.h"
+#include "vsh-table.h"
 
 #define VIRSH_COMMON_OPT_NETWORK(_helpstr, cflags) \
 {.name = "network", \
@@ -677,6 +678,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 bool optUUID = vshCommandOptBool(cmd, "uuid");
 char uuid[VIR_UUID_STRING_BUFLEN];
 unsigned int flags = VIR_CONNECT_LIST_NETWORKS_ACTIVE;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "inactive"))
 flags = VIR_CONNECT_LIST_NETWORKS_INACTIVE;
@@ -705,10 +707,10 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 return false;
 
 if (optTable) {
-vshPrintExtra(ctl, " %-20s %-10s %-13s %s\n", _("Name"), _("State"),
-  _("Autostart"), _("Persistent"));
-vshPrintExtra(ctl,
-  
"--\n");
+table = vshTableNew(_("Name"), _("State"), _("Autostart"),
+_("Persistent"), NULL);
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->nnets; i++) {
@@ -722,11 +724,15 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 else
 autostartStr = is_autostart ? _("yes") : _("no");
 
-vshPrint(ctl, " %-20s %-10s %-13s %s\n",
- virNetworkGetName(network),
- virNetworkIsActive(network) ? _("active") : _("inactive"),
- autostartStr,
- virNetworkIsPersistent(network) ? _("yes") : _("no"));
+if (vshTableRowAppend(table,
+  virNetworkGetName(network),
+  virNetworkIsActive(network) ?
+  _("active") : _("inactive"),
+  autostartStr,
+  virNetworkIsPersistent(network) ?
+  _("yes") : _("no"),
+  NULL) < 0)
+goto cleanup;
 } else if (optUUID) {
 if (virNetworkGetUUIDString(network, uuid) < 0) {
 vshError(ctl, "%s", _("Failed to get network's UUID"));
@@ -738,8 +744,12 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 }
 }
 
+if (optTable)
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
  cleanup:
+vshTableFree(table);
 virshNetworkListFree(list);
 return ret;
 }
@@ -1351,6 +1361,7 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 size_t i;
 unsigned int flags = 0;
 virNetworkPtr network = NULL;
+vshTablePtr table = NULL;
 
 if (vshCommandOptStringReq(ctl, cmd, "mac", ) < 0)
 return false;
@@ -1366,15 +1377,15 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 /* Sort the list according to MAC Address/IAID */
 qsort(leases, nleases, sizeof(*leases), virshNetworkDHCPLeaseSorter);
 
-vshPrintExtra(ctl, " %-20s %-18s %-9s %-25s %-15s %s\n%s%s\n",
-  _("Expiry Time"), _("MAC address"), _("Protocol"),
-  _("IP address"), _("Hostname"), _("Client ID or DUID"),
-  "--",
-  "-");
+table = vshTableNew(_("Expiry Time"), _("MAC address"), _("Protocol"),
+_("IP address"), _("Hostname"), _("Client ID or DUID"),
+NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < nleases; i++) {
 const char *typestr = NULL;
-char *cidr_format = NULL;
+VIR_AUTOFREE(char *) cidr_format = NULL;
 virNetworkDHCPLeasePtr lease = leases[i];
 time_t expirytime_tmp = lease->expirytime;
 struct tm ts;
@@ -1390,17 +1401,23 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 ignore_value(virAsprintf(_format, "%s/%d",
  lease->ipaddr, lease->prefix));
 
-   

[libvirt] [PATCH v2 01/13] virsh: Implement vsh-table to iface-list

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-interface.c | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/tools/virsh-interface.c b/tools/virsh-interface.c
index 50518c667b..1eb1a27ac7 100644
--- a/tools/virsh-interface.c
+++ b/tools/virsh-interface.c
@@ -48,6 +48,7 @@
 #include "virutil.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 virInterfacePtr
 virshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
@@ -356,6 +357,8 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 unsigned int flags = VIR_CONNECT_LIST_INTERFACES_ACTIVE;
 virshInterfaceListPtr list = NULL;
 size_t i;
+bool ret = false;
+vshTablePtr table = NULL;
 
 if (inactive)
 flags = VIR_CONNECT_LIST_INTERFACES_INACTIVE;
@@ -366,21 +369,29 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 if (!(list = virshInterfaceListCollect(ctl, flags)))
 return false;
 
-vshPrintExtra(ctl, " %-20s %-10s %s\n", _("Name"), _("State"),
-  _("MAC Address"));
-vshPrintExtra(ctl, 
"---\n");
+table = vshTableNew(_("Name"), _("State"), _("MAC Address"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nifaces; i++) {
 virInterfacePtr iface = list->ifaces[i];
 
-vshPrint(ctl, " %-20s %-10s %s\n",
- virInterfaceGetName(iface),
- virInterfaceIsActive(iface) ? _("active") : _("inactive"),
- virInterfaceGetMACString(iface));
+if (vshTableRowAppend(table,
+  virInterfaceGetName(iface),
+  virInterfaceIsActive(iface) ? _("active")
+  : _("inactive"),
+  virInterfaceGetMACString(iface),
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
+ret = true;
+ cleanup:
+vshTableFree(table);
 virshInterfaceListFree(list);
-return true;
+return ret;
 }
 
 /*
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 04/13] virsh: Implement vshTable API to nwfilter-list and nwfilterbinding-list

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-nwfilter.c | 47 +-
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c
index 1cdbe5053a..b680ea082c 100644
--- a/tools/virsh-nwfilter.c
+++ b/tools/virsh-nwfilter.c
@@ -31,6 +31,7 @@
 #include "viralloc.h"
 #include "virfile.h"
 #include "virutil.h"
+#include "vsh-table.h"
 
 virNWFilterPtr
 virshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
@@ -359,26 +360,35 @@ cmdNWFilterList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 {
 size_t i;
 char uuid[VIR_UUID_STRING_BUFLEN];
+bool ret = false;
 virshNWFilterListPtr list = NULL;
+vshTablePtr table = NULL;
 
 if (!(list = virshNWFilterListCollect(ctl, 0)))
 return false;
 
-vshPrintExtra(ctl, " %-36s  %-20s \n", _("UUID"), _("Name"));
-vshPrintExtra(ctl, "-"
-   "-\n");
+table = vshTableNew(_("UUID"), _("Name"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nfilters; i++) {
 virNWFilterPtr nwfilter = list->filters[i];
 
 virNWFilterGetUUIDString(nwfilter, uuid);
-vshPrint(ctl, " %-36s  %-20s\n",
- uuid,
- virNWFilterGetName(nwfilter));
+if (vshTableRowAppend(table,
+  uuid,
+  virNWFilterGetName(nwfilter),
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
+ret = true;
+ cleanup:
+vshTableFree(table);
 virshNWFilterListFree(list);
-return true;
+return ret;
 }
 
 /*
@@ -714,25 +724,34 @@ static bool
 cmdNWFilterBindingList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
 {
 size_t i;
+bool ret = false;
 virshNWFilterBindingListPtr list = NULL;
+vshTablePtr table = NULL;
 
 if (!(list = virshNWFilterBindingListCollect(ctl, 0)))
 return false;
 
-vshPrintExtra(ctl, " %-20s  %-20s \n", _("Port Dev"), _("Filter"));
-vshPrintExtra(ctl, "-"
-   "-\n");
+table = vshTableNew(_("Port Dev"), _("Filter"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nbindings; i++) {
 virNWFilterBindingPtr binding = list->bindings[i];
 
-vshPrint(ctl, " %-20s  %-20s\n",
- virNWFilterBindingGetPortDev(binding),
- virNWFilterBindingGetFilterName(binding));
+if (vshTableRowAppend(table,
+  virNWFilterBindingGetPortDev(binding),
+  virNWFilterBindingGetFilterName(binding),
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
+ret = true;
+ cleanup:
+vshTableFree(table);
 virshNWFilterBindingListFree(list);
-return true;
+return ret;
 }
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 13/13] virt-admin: Implement vshTable API to server-list and client-list

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virt-admin.c | 47 ++
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index 63822bc13e..d119e4d960 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -40,6 +40,7 @@
 #include "virgettext.h"
 #include "virtime.h"
 #include "virt-admin-completer.h"
+#include "vsh-table.h"
 
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
@@ -382,6 +383,7 @@ cmdSrvList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 char *uri = NULL;
 virAdmServerPtr *srvs = NULL;
 vshAdmControlPtr priv = ctl->privData;
+vshTablePtr table = NULL;
 
 /* Obtain a list of available servers on the daemon */
 if ((nsrvs = virAdmConnectListServers(priv->conn, , 0)) < 0) {
@@ -391,13 +393,27 @@ cmdSrvList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 goto cleanup;
 }
 
-vshPrintExtra(ctl, " %-5s %-15s\n", "Id", "Name");
-vshPrintExtra(ctl, "---\n");
-for (i = 0; i < nsrvs; i++)
-vshPrint(ctl, " %-5zu %-15s\n", i, virAdmServerGetName(srvs[i]));
+table = vshTableNew(_("Id"), _("Name"), NULL);
+if (!table)
+goto cleanup;
+
+for (i = 0; i < nsrvs; i++) {
+VIR_AUTOFREE(char *) idStr = NULL;
+if (virAsprintf(, "%lu", i) < 0)
+goto cleanup;
+
+if (vshTableRowAppend(table,
+  idStr,
+  virAdmServerGetName(srvs[i]),
+  NULL) < 0)
+goto cleanup;
+}
+
+vshTablePrintToStdout(table, ctl);
 
 ret = true;
  cleanup:
+vshTableFree(table);
 if (srvs) {
 for (i = 0; i < nsrvs; i++)
 virAdmServerFree(srvs[i]);
@@ -613,10 +629,10 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
 const char *srvname = NULL;
 unsigned long long id;
 virClientTransport transport;
-char *timestr = NULL;
 virAdmServerPtr srv = NULL;
 virAdmClientPtr *clts = NULL;
 vshAdmControlPtr priv = ctl->privData;
+vshTablePtr table = NULL;
 
 if (vshCommandOptStringReq(ctl, cmd, "server", ) < 0)
 return false;
@@ -631,12 +647,13 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 }
 
-vshPrintExtra(ctl, " %-5s %-15s %-15s\n%s\n", _("Id"), _("Transport"),
-  _("Connected since"),
-  "-"
-  "-");
+table = vshTableNew(_("Id"), _("Transport"), _("Connected sice"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < nclts; i++) {
+VIR_AUTOFREE(char *) timestr = NULL;
+VIR_AUTOFREE(char *) idStr = NULL;
 virAdmClientPtr client = clts[i];
 id = virAdmClientGetID(client);
 transport = virAdmClientGetTransport(client);
@@ -644,14 +661,20 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
  ) < 0)
 goto cleanup;
 
-vshPrint(ctl, " %-5llu %-15s %-15s\n",
- id, vshAdmClientTransportToString(transport), timestr);
-VIR_FREE(timestr);
+if (virAsprintf(, "%llu", id) < 0)
+goto cleanup;
+if (vshTableRowAppend(table, idStr,
+  vshAdmClientTransportToString(transport),
+  timestr, NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 if (clts) {
 for (i = 0; i < nclts; i++)
 virAdmClientFree(clts[i]);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 03/13] virsh: Implement vshTable API to secret-list

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-secret.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index 670beea706..87239ff60b 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -35,6 +35,7 @@
 #include "virsecret.h"
 #include "virstring.h"
 #include "virtime.h"
+#include "vsh-table.h"
 
 static virSecretPtr
 virshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name)
@@ -507,6 +508,7 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 virshSecretListPtr list = NULL;
 bool ret = false;
 unsigned int flags = 0;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "ephemeral"))
 flags |= VIR_CONNECT_LIST_SECRETS_EPHEMERAL;
@@ -523,15 +525,17 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 if (!(list = virshSecretListCollect(ctl, flags)))
 return false;
 
-vshPrintExtra(ctl, " %-36s  %s\n", _("UUID"), _("Usage"));
-vshPrintExtra(ctl, ""
-   "\n");
+table = vshTableNew(_("UUID"), _("Usage"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nsecrets; i++) {
 virSecretPtr sec = list->secrets[i];
 int usageType = virSecretGetUsageType(sec);
 const char *usageStr = virSecretUsageTypeToString(usageType);
 char uuid[VIR_UUID_STRING_BUFLEN];
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+VIR_AUTOFREE(char *) usage = NULL;
 
 if (virSecretGetUUIDString(sec, uuid) < 0) {
 vshError(ctl, "%s", _("Failed to get uuid of secret"));
@@ -539,18 +543,26 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 }
 
 if (usageType) {
-vshPrint(ctl, " %-36s  %s %s\n",
- uuid, usageStr,
- virSecretGetUsageID(sec));
+virBufferStrcat(, usageStr, " ",
+virSecretGetUsageID(sec), NULL);
+usage = virBufferContentAndReset();
+if (!usage)
+goto cleanup;
+
+if (vshTableRowAppend(table, uuid, usage, NULL) < 0)
+goto cleanup;
 } else {
-vshPrint(ctl, " %-36s  %s\n",
- uuid, _("Unused"));
+if (vshTableRowAppend(table, uuid, _("Unused"), NULL) < 0)
+goto cleanup;
 }
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 virshSecretListFree(list);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 06/13] virsh: Set up cmdDomblkinfo() and cmdDomblkinfoPrint() for vshTable API implementation

2018-09-21 Thread Simon Kobyda
I've moved all the printing from cmdDomblkinfoPrint() to cmdDomblkinfo(),
and renamed the cmdDomblkinfoPrint() to cmdDomblkinfoGet(), since nature of
that function changed from gathering and printing informations only to
gathering information. This I believe simplifies the functions and
makes the implementation of vshTable API simpler.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 78 +---
 1 file changed, 36 insertions(+), 42 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index adc5bb1a7a..cb48f9a7be 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -406,33 +406,23 @@ static const vshCmdOptDef opts_domblkinfo[] = {
 {.name = NULL}
 };
 
-static void
-cmdDomblkinfoPrint(vshControl *ctl,
+static bool
+cmdDomblkinfoGet(vshControl *ctl,
const virDomainBlockInfo *info,
-   const char *device,
-   bool human, bool title)
+   char **cap,
+   char **alloc,
+   char **phy,
+   bool human)
 {
-char *cap = NULL;
-char *alloc = NULL;
-char *phy = NULL;
-
-if (title) {
-vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"),
-  _("Capacity"), _("Allocation"), _("Physical"));
-vshPrintExtra(ctl, "-"
-  "\n");
-return;
-}
-
 if (info->capacity == 0 && info->allocation == 0 && info->physical == 0) {
-cap = vshStrdup(ctl, "-");
-alloc = vshStrdup(ctl, "-");
-phy = vshStrdup(ctl, "-");
+*cap = vshStrdup(ctl, "-");
+*alloc = vshStrdup(ctl, "-");
+*phy = vshStrdup(ctl, "-");
 } else if (!human) {
-if (virAsprintf(, "%llu", info->capacity) < 0 ||
-virAsprintf(, "%llu", info->allocation) < 0 ||
-virAsprintf(, "%llu", info->physical) < 0)
-goto cleanup;
+if (virAsprintf(cap, "%llu", info->capacity) < 0 ||
+virAsprintf(alloc, "%llu", info->allocation) < 0 ||
+virAsprintf(phy, "%llu", info->physical) < 0)
+return false;
 } else {
 double val_cap, val_alloc, val_phy;
 const char *unit_cap, *unit_alloc, *unit_phy;
@@ -441,24 +431,13 @@ cmdDomblkinfoPrint(vshControl *ctl,
 val_alloc = vshPrettyCapacity(info->allocation, _alloc);
 val_phy = vshPrettyCapacity(info->physical, _phy);
 
-if (virAsprintf(, "%.3lf %s", val_cap, unit_cap) < 0 ||
-virAsprintf(, "%.3lf %s", val_alloc, unit_alloc) < 0 ||
-virAsprintf(, "%.3lf %s", val_phy, unit_phy) < 0)
-goto cleanup;
-}
-
-if (device) {
-vshPrint(ctl, "%-10s %-15s %-15s %-15s\n", device, cap, alloc, phy);
-} else {
-vshPrint(ctl, "%-15s %s\n", _("Capacity:"), cap);
-vshPrint(ctl, "%-15s %s\n", _("Allocation:"), alloc);
-vshPrint(ctl, "%-15s %s\n", _("Physical:"), phy);
+if (virAsprintf(cap, "%.3lf %s", val_cap, unit_cap) < 0 ||
+virAsprintf(alloc, "%.3lf %s", val_alloc, unit_alloc) < 0 ||
+virAsprintf(phy, "%.3lf %s", val_phy, unit_phy) < 0)
+return false;
 }
 
- cleanup:
-VIR_FREE(cap);
-VIR_FREE(alloc);
-VIR_FREE(phy);
+return true;
 }
 
 
@@ -478,6 +457,9 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 xmlNodePtr *disks = NULL;
 char *target = NULL;
 char *protocol = NULL;
+char *cap = NULL;
+char *alloc = NULL;
+char *phy = NULL;
 
 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
 return false;
@@ -502,7 +484,10 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 
 /* print the title */
-cmdDomblkinfoPrint(ctl, NULL, NULL, false, true);
+vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"),
+  _("Capacity"), _("Allocation"), _("Physical"));
+vshPrintExtra(ctl, "-"
+  "\n");
 
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
@@ -525,7 +510,9 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 }
 }
 
-cmdDomblkinfoPrint(ctl, , target, human, false);
+if (!cmdDomblkinfoGet(ctl, , , , , human))
+goto cleanup;
+ 

[libvirt] [PATCH v2 07/13] virsh: Implement vshTable API to domblkinfo

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index cb48f9a7be..80c7e8a99e 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -460,6 +460,7 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 char *cap = NULL;
 char *alloc = NULL;
 char *phy = NULL;
+vshTablePtr table = NULL;
 
 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
 return false;
@@ -483,11 +484,10 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 if (ndisks < 0)
 goto cleanup;
 
-/* print the title */
-vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"),
-  _("Capacity"), _("Allocation"), _("Physical"));
-vshPrintExtra(ctl, "-"
-  "\n");
+/* title */
+table = vshTableNew(_("Target"), _("Capacity"), _("Allocation"), 
_("Physical"), NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
@@ -512,11 +512,15 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 
 if (!cmdDomblkinfoGet(ctl, , , , , human))
 goto cleanup;
-vshPrint(ctl, "%-10s %-15s %-15s %-15s\n", target, cap, alloc, 
phy);
+if (vshTableRowAppend(table, target, cap, alloc, phy, NULL) < 0)
+goto cleanup;
 
 VIR_FREE(target);
 VIR_FREE(protocol);
 }
+
+vshTablePrintToStdout(table, ctl);
+
 } else {
 if (virDomainGetBlockInfo(dom, device, , 0) < 0)
 goto cleanup;
@@ -531,6 +535,7 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 ret = true;
 
  cleanup:
+vshTableFree(table);
 VIR_FREE(cap);
 VIR_FREE(alloc);
 VIR_FREE(phy);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 05/13] virsh: Implement vshTable API to snapshot-list.

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-snapshot.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index a4ea959230..73861957ba 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -41,6 +41,7 @@
 #include "virstring.h"
 #include "virxml.h"
 #include "conf/snapshot_conf.h"
+#include "vsh-table.h"
 
 /* Helper for snapshot-create and snapshot-create-as */
 static bool
@@ -1487,6 +1488,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 char *parent_snap = NULL;
 virDomainSnapshotPtr start = NULL;
 virshSnapshotListPtr snaplist = NULL;
+vshTablePtr table = NULL;
 
 VSH_EXCLUSIVE_OPTIONS_VAR(tree, name);
 VSH_EXCLUSIVE_OPTIONS_VAR(parent, roots);
@@ -1547,15 +1549,12 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 
 if (!tree && !name) {
 if (parent)
-vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
-  _("Name"), _("Creation Time"), _("State"),
-  _("Parent"));
+table = vshTableNew(_("Name"), _("Creation Time"), _("State"), 
_("Parent"), NULL);
 else
-vshPrintExtra(ctl, " %-20s %-25s %s",
-  _("Name"), _("Creation Time"), _("State"));
-vshPrintExtra(ctl, "\n"
-   "--"
-   "--\n");
+table = vshTableNew(_("Name"), _("Creation Time"), _("State"), 
NULL);
+
+if (!table)
+goto cleanup;
 }
 
 if (tree) {
@@ -1614,13 +1613,20 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
  _info);
 
-if (parent)
-vshPrint(ctl, " %-20s %-25s %-15s %s\n",
- snap_name, timestr, state, parent_snap);
-else
-vshPrint(ctl, " %-20s %-25s %s\n", snap_name, timestr, state);
+if (parent) {
+if (vshTableRowAppend(table, snap_name, timestr, state, 
parent_snap,
+  NULL) < 0)
+goto cleanup;
+} else {
+if (vshTableRowAppend(table, snap_name, timestr, state,
+  NULL) < 0)
+goto cleanup;
+}
 }
 
+if (table)
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
@@ -1633,6 +1639,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 xmlFreeDoc(xml);
 VIR_FREE(doc);
 virshDomainFree(dom);
+vshTableFree(table);
 
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 10/13] virsh: Implement vshTable API to vcpupin, iothreadinfo, domfsinfo

2018-09-21 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain.c | 98 +++-
 1 file changed, 70 insertions(+), 28 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c1cff9fe2d..2a416b919a 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -59,6 +59,7 @@
 #include "virxml.h"
 #include "virsh-nodedev.h"
 #include "viruri.h"
+#include "vsh-table.h"
 
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
@@ -6905,6 +6906,7 @@ virshVcpuPinQuery(vshControl *ctl,
 size_t i;
 int ncpus;
 bool ret = false;
+vshTablePtr table = NULL;
 
 if ((ncpus = virshCPUCountCollect(ctl, dom, countFlags, true)) < 0) {
 if (ncpus == -1) {
@@ -6913,7 +6915,7 @@ virshVcpuPinQuery(vshControl *ctl,
 else
 vshError(ctl, "%s", _("cannot get vcpupin for transient 
domain"));
 }
-return false;
+goto cleanup;
 }
 
 if (got_vcpu && vcpu >= ncpus) {
@@ -6927,28 +6929,39 @@ virshVcpuPinQuery(vshControl *ctl,
 vshError(ctl,
  _("vcpu %d is out of range of persistent cpu count %d"),
  vcpu, ncpus);
-return false;
+goto cleanup;
 }
 
 cpumaplen = VIR_CPU_MAPLEN(maxcpu);
 cpumap = vshMalloc(ctl, ncpus * cpumaplen);
 if ((ncpus = virDomainGetVcpuPinInfo(dom, ncpus, cpumap,
  cpumaplen, flags)) >= 0) {
-vshPrintExtra(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity"));
-vshPrintExtra(ctl, "--\n");
+table = vshTableNew(_("VCPU"), _("CPU Affinity"), NULL);
+if (!table)
+goto cleanup;
+
 for (i = 0; i < ncpus; i++) {
+VIR_AUTOFREE(char *) pinInfo = NULL;
+VIR_AUTOFREE(char *) vcpuStr = NULL;
 if (got_vcpu && i != vcpu)
 continue;
 
-vshPrint(ctl, "%4zu: ", i);
-ret = virshPrintPinInfo(ctl, VIR_GET_CPUMAP(cpumap, cpumaplen, i),
-cpumaplen);
-vshPrint(ctl, "\n");
-if (!ret)
-break;
+if (!(pinInfo = virBitmapDataFormat(cpumap, cpumaplen)))
+goto cleanup;
+
+if (virAsprintf(, "%lu", i) < 0)
+goto cleanup;
+
+if (vshTableRowAppend(table, vcpuStr, pinInfo, NULL) < 0)
+goto cleanup;
 }
+
+vshTablePrintToStdout(table, ctl);
 }
 
+ret = true;
+ cleanup:
+vshTableFree(table);
 VIR_FREE(cpumap);
 return ret;
 }
@@ -7520,6 +7533,7 @@ cmdIOThreadInfo(vshControl *ctl, const vshCmd *cmd)
 int maxcpu;
 unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
 virshControlPtr priv = ctl->privData;
+vshTablePtr table = NULL;
 
 VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
 VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
@@ -7545,19 +7559,30 @@ cmdIOThreadInfo(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 }
 
-vshPrintExtra(ctl, " %-15s %-15s\n",
-  _("IOThread ID"), _("CPU Affinity"));
-vshPrintExtra(ctl, 
"---\n");
+table = vshTableNew(_("IOThread ID"), _("CPU Affinity"), NULL);
+if (!table)
+goto cleanup;
+
 for (i = 0; i < niothreads; i++) {
+VIR_AUTOFREE(char *) pinInfo = NULL;
+VIR_AUTOFREE(char *) iothreadIdStr = NULL;
 
-vshPrint(ctl, " %-15u ", info[i]->iothread_id);
-ignore_value(virshPrintPinInfo(ctl, info[i]->cpumap, 
info[i]->cpumaplen));
-vshPrint(ctl, "\n");
-virDomainIOThreadInfoFree(info[i]);
+if (virAsprintf(, "%u", info[i]->iothread_id) < 0)
+goto cleanup;
+
+ignore_value(pinInfo = virBitmapDataFormat(info[i]->cpumap, 
info[i]->cpumaplen));
+
+if (vshTableRowAppend(table, iothreadIdStr, pinInfo ? pinInfo : "", 
NULL) < 0)
+goto cleanup;
 }
-VIR_FREE(info);
+
+vshTablePrintToStdout(table, ctl);
 
  cleanup:
+for (i = 0; i < niothreads; i++)
+virDomainIOThreadInfoFree(info[i]);
+VIR_FREE(info);
+vshTableFree(table);
 virshDomainFree(dom);
 return niothreads >= 0;
 }
@@ -13778,6 +13803,7 @@ cmdDomFSInfo(vshControl *ctl, const vshCmd *cmd)
 int ret = -1;
 size_t i, j;
 virDomainFSInfoPtr *info;
+vshTablePtr table = NULL;
 
 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
 return false;
@@ -13793,25 +13819,41 @@ cmdDomFSInfo(vshControl *ctl, const vshCmd *cmd)
 }
 
 if (info) {
-

[libvirt] [PATCH v2 00/13] Implement vsh-table API to virsh and virt-admin

2018-09-21 Thread Simon Kobyda
API is implemented in virsh and virt-admin. It fixes problems with
table-alignment, makes tables more readable and deals with unicode.
Table however could not be implemented in places, which do use simple
lists, or table implementation would change content of output,
which users might rely on.
If you know about other place where it could be implemented,
let me know.

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Changes in v2:
- Implemented gettext function
- Fixed few possible leaks caused by inserting "goto cleanup" statements
- Implemented VIR_AUTOFREE where it's appropriate

Simon Kobyda (13):
  virsh: Implement vsh-table to iface-list
  virsh: Implement vshTable API to net-list and net-dhcp-leases
  virsh: Implement vshTable API to secret-list
  virsh: Implement vshTable API to nwfilter-list and
nwfilterbinding-list
  virsh: Implement vshTable API to snapshot-list.
  virsh: Set up cmdDomblkinfo() and cmdDomblkinfoPrint() for vshTable
API implementation
  virsh: Implement vshTable API to domblkinfo
  virsh: Implement vshTable API to domblklist
  virsh: Implement vshTable API to domiflist
  virsh: Implement vshTable API to vcpupin, iothreadinfo, domfsinfo
  virsh: Implement vshTable API to pool-list
  virsh: Implement vshTable API to vol-list
  virt-admin: Implement vshTable API to server-list and client-list

 tools/virsh-domain-monitor.c | 147 ---
 tools/virsh-domain.c |  98 +++--
 tools/virsh-interface.c  |  27 --
 tools/virsh-network.c|  59 -
 tools/virsh-nwfilter.c   |  47 +++---
 tools/virsh-pool.c   | 162 +++
 tools/virsh-secret.c |  28 --
 tools/virsh-snapshot.c   |  33 ---
 tools/virsh-volume.c | 129 ++--
 tools/virt-admin.c   |  47 +++---
 10 files changed, 371 insertions(+), 406 deletions(-)

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 13/13] virt-admin: Implement vshTable API to server-list and client-list

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virt-admin.c | 46 --
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index 63822bc13e..ac4c72efec 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -40,6 +40,7 @@
 #include "virgettext.h"
 #include "virtime.h"
 #include "virt-admin-completer.h"
+#include "vsh-table.h"
 
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
@@ -382,6 +383,7 @@ cmdSrvList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 char *uri = NULL;
 virAdmServerPtr *srvs = NULL;
 vshAdmControlPtr priv = ctl->privData;
+vshTablePtr table = NULL;
 
 /* Obtain a list of available servers on the daemon */
 if ((nsrvs = virAdmConnectListServers(priv->conn, , 0)) < 0) {
@@ -391,13 +393,28 @@ cmdSrvList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 goto cleanup;
 }
 
-vshPrintExtra(ctl, " %-5s %-15s\n", "Id", "Name");
-vshPrintExtra(ctl, "---\n");
-for (i = 0; i < nsrvs; i++)
-vshPrint(ctl, " %-5zu %-15s\n", i, virAdmServerGetName(srvs[i]));
+table = vshTableNew("Id", "Name", NULL);
+if (!table)
+goto cleanup;
+
+for (i = 0; i < nsrvs; i++) {
+char *idStr;
+if (virAsprintf(, "%lu", i) < 0)
+goto cleanup;
+
+if (vshTableRowAppend(table,
+  idStr,
+  virAdmServerGetName(srvs[i]),
+  NULL) < 0)
+goto cleanup;
+VIR_FREE(idStr);
+}
+
+vshTablePrintToStdout(table, ctl);
 
 ret = true;
  cleanup:
+vshTableFree(table);
 if (srvs) {
 for (i = 0; i < nsrvs; i++)
 virAdmServerFree(srvs[i]);
@@ -617,6 +634,7 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
 virAdmServerPtr srv = NULL;
 virAdmClientPtr *clts = NULL;
 vshAdmControlPtr priv = ctl->privData;
+vshTablePtr table = NULL;
 
 if (vshCommandOptStringReq(ctl, cmd, "server", ) < 0)
 return false;
@@ -631,12 +649,12 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 }
 
-vshPrintExtra(ctl, " %-5s %-15s %-15s\n%s\n", _("Id"), _("Transport"),
-  _("Connected since"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Transport", "Connected sice", NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < nclts; i++) {
+char *idStr;
 virAdmClientPtr client = clts[i];
 id = virAdmClientGetID(client);
 transport = virAdmClientGetTransport(client);
@@ -644,14 +662,22 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
  ) < 0)
 goto cleanup;
 
-vshPrint(ctl, " %-5llu %-15s %-15s\n",
- id, vshAdmClientTransportToString(transport), timestr);
+if (virAsprintf(, "%llu", id) < 0)
+goto cleanup;
+if (vshTableRowAppend(table, idStr,
+  vshAdmClientTransportToString(transport),
+  timestr, NULL) < 0)
+goto cleanup;
 VIR_FREE(timestr);
+VIR_FREE(idStr);
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 if (clts) {
 for (i = 0; i < nclts; i++)
 virAdmClientFree(clts[i]);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 12/13] virsh: Implement vshTable API to vol-list

2018-09-18 Thread Simon Kobyda
Local lengthy unicode-unreliable table formatting was replaced by new
API. Great example of how new API saves space and time.
Removed a lot of string lenght calculation used by the local table.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-volume.c | 127 +--
 1 file changed, 27 insertions(+), 100 deletions(-)

diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 42d11701ec..071882c628 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -42,6 +42,7 @@
 #include "virsh-pool.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 #define VIRSH_COMMON_OPT_POOL_FULL \
 VIRSH_COMMON_OPT_POOL(N_("pool name or uuid"), \
@@ -1382,16 +1383,11 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 {
 virStorageVolInfo volumeInfo;
 virStoragePoolPtr pool;
-char *outputStr = NULL;
 const char *unit;
 double val;
 bool details = vshCommandOptBool(cmd, "details");
 size_t i;
 bool ret = false;
-int stringLength = 0;
-size_t allocStrLength = 0, capStrLength = 0;
-size_t nameStrLength = 0, pathStrLength = 0;
-size_t typeStrLength = 0;
 struct volInfoText {
 char *allocation;
 char *capacity;
@@ -1400,6 +1396,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 };
 struct volInfoText *volInfoTexts = NULL;
 virshStorageVolListPtr list = NULL;
+vshTablePtr table = NULL;
 
 /* Look up the pool information given to us by the user */
 if (!(pool = virshCommandOptPool(ctl, cmd, "pool", NULL)))
@@ -1446,36 +1443,6 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 "%.2lf %s", val, unit) < 0)
 goto cleanup;
 }
-
-/* Remember the largest length for each output string.
- * This lets us displaying header and volume information rows
- * using a single, properly sized, printf style output string.
- */
-
-/* Keep the length of name string if longest so far */
-stringLength = strlen(virStorageVolGetName(list->vols[i]));
-if (stringLength > nameStrLength)
-nameStrLength = stringLength;
-
-/* Keep the length of path string if longest so far */
-stringLength = strlen(volInfoTexts[i].path);
-if (stringLength > pathStrLength)
-pathStrLength = stringLength;
-
-/* Keep the length of type string if longest so far */
-stringLength = strlen(volInfoTexts[i].type);
-if (stringLength > typeStrLength)
-typeStrLength = stringLength;
-
-/* Keep the length of capacity string if longest so far */
-stringLength = strlen(volInfoTexts[i].capacity);
-if (stringLength > capStrLength)
-capStrLength = stringLength;
-
-/* Keep the length of allocation string if longest so far */
-stringLength = strlen(volInfoTexts[i].allocation);
-if (stringLength > allocStrLength)
-allocStrLength = stringLength;
 }
 }
 
@@ -1487,14 +1454,20 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 /* Output basic info then return if --details option not selected */
 if (!details) {
 /* The old output format */
-vshPrintExtra(ctl, " %-20s %-40s\n", _("Name"), _("Path"));
-vshPrintExtra(ctl, "---"
-   "---\n");
+table = vshTableNew("Name", "Path", NULL);
+if (!table)
+goto cleanup;
+
 for (i = 0; i < list->nvols; i++) {
-vshPrint(ctl, " %-20s %-40s\n", 
virStorageVolGetName(list->vols[i]),
- volInfoTexts[i].path);
+if (vshTableRowAppend(table,
+  virStorageVolGetName(list->vols[i]),
+  volInfoTexts[i].path,
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
 /* Cleanup and return */
 ret = true;
 goto cleanup;
@@ -1502,75 +1475,30 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 
 /* We only get here if the --details option was selected. */
 
-/* Use the length of name header string if it's longest */
-stringLength = strlen(_("Name"));
-if (stringLength > nameStrLength)
-nameStrLength = stringLength;
-
-/* Use the length of path header string if it's longest */
-stringLength = strlen(_("Path"));
-if (stringLength >

[libvirt] [PATCH 07/13] virsh: Implement vshTable API to domblkinfo

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index cb48f9a7be..05db825716 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -460,6 +460,7 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 char *cap = NULL;
 char *alloc = NULL;
 char *phy = NULL;
+vshTablePtr table = NULL;
 
 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
 return false;
@@ -483,11 +484,10 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 if (ndisks < 0)
 goto cleanup;
 
-/* print the title */
-vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"),
-  _("Capacity"), _("Allocation"), _("Physical"));
-vshPrintExtra(ctl, "-"
-  "\n");
+/* title */
+table = vshTableNew("Target", "Capacity", "Allocation", "Physical", 
NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
@@ -512,11 +512,15 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 
 if (!cmdDomblkinfoGet(ctl, , , , , human))
 goto cleanup;
-vshPrint(ctl, "%-10s %-15s %-15s %-15s\n", target, cap, alloc, 
phy);
+if (vshTableRowAppend(table, target, cap, alloc, phy, NULL) < 0)
+goto cleanup;
 
 VIR_FREE(target);
 VIR_FREE(protocol);
 }
+
+vshTablePrintToStdout(table, ctl);
+
 } else {
 if (virDomainGetBlockInfo(dom, device, , 0) < 0)
 goto cleanup;
@@ -531,6 +535,7 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 ret = true;
 
  cleanup:
+vshTableFree(table);
 VIR_FREE(cap);
 VIR_FREE(alloc);
 VIR_FREE(phy);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 11/13] virsh: Implement vshTable API to pool-list

2018-09-18 Thread Simon Kobyda
Local lengthy unicode-unreliable table formatting was replaced by new
API. Great example of how new API saves space and time.
Removed a lot of string lenght canculation used by the local table.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-pool.c | 160 +
 1 file changed, 30 insertions(+), 130 deletions(-)

diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index 89206a48f5..724864a935 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -33,6 +33,7 @@
 #include "conf/storage_conf.h"
 #include "virstring.h"
 #include "virtime.h"
+#include "vsh-table.h"
 
 #define VIRSH_COMMON_OPT_POOL_FULL(cflags) \
 VIRSH_COMMON_OPT_POOL(N_("pool name or uuid"), cflags)
@@ -1113,10 +1114,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 virStoragePoolInfo info;
 size_t i;
 bool ret = false;
-size_t stringLength = 0, nameStrLength = 0;
-size_t autostartStrLength = 0, persistStrLength = 0;
-size_t stateStrLength = 0, capStrLength = 0;
-size_t allocStrLength = 0, availStrLength = 0;
 struct poolInfoText {
 char *state;
 char *autostart;
@@ -1133,7 +1130,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 bool inactive, all;
 bool uuid = false;
 bool name = false;
-char *outputStr = NULL;
+vshTablePtr table = NULL;
 
 inactive = vshCommandOptBool(cmd, "inactive");
 all = vshCommandOptBool(cmd, "all");
@@ -1260,11 +1257,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 else
 poolInfoTexts[i].persistent = vshStrdup(ctl, persistent ?
  _("yes") : _("no"));
-
-/* Keep the length of persistent string if longest so far */
-stringLength = strlen(poolInfoTexts[i].persistent);
-if (stringLength > persistStrLength)
-persistStrLength = stringLength;
 }
 
 /* Collect further extended information about the pool */
@@ -1310,21 +1302,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 poolInfoTexts[i].allocation = vshStrdup(ctl, _("-"));
 poolInfoTexts[i].available = vshStrdup(ctl, _("-"));
 }
-
-/* Keep the length of capacity string if longest so far */
-stringLength = strlen(poolInfoTexts[i].capacity);
-if (stringLength > capStrLength)
-capStrLength = stringLength;
-
-/* Keep the length of allocation string if longest so far */
-stringLength = strlen(poolInfoTexts[i].allocation);
-if (stringLength > allocStrLength)
-allocStrLength = stringLength;
-
-/* Keep the length of available string if longest so far */
-stringLength = strlen(poolInfoTexts[i].available);
-if (stringLength > availStrLength)
-availStrLength = stringLength;
 } else {
 /* --details option was not specified, only active/inactive
  * state strings are used */
@@ -1334,21 +1311,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 poolInfoTexts[i].state = vshStrdup(ctl, _("inactive"));
}
 }
-
-/* Keep the length of name string if longest so far */
-stringLength = strlen(virStoragePoolGetName(list->pools[i]));
-if (stringLength > nameStrLength)
-nameStrLength = stringLength;
-
-/* Keep the length of state string if longest so far */
-stringLength = strlen(poolInfoTexts[i].state);
-if (stringLength > stateStrLength)
-stateStrLength = stringLength;
-
-/* Keep the length of autostart string if longest so far */
-stringLength = strlen(poolInfoTexts[i].autostart);
-if (stringLength > autostartStrLength)
-autostartStrLength = stringLength;
 }
 
 /* If the --details option wasn't selected, we output the pool
@@ -1376,19 +1338,23 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 }
 
 /* Output old style header */
-vshPrintExtra(ctl, " %-20s %-10s %-10s\n", _("Name"), _("State"),
-  _("Autostart"));
-vshPrintExtra(ctl, "---\n");
+table = vshTableNew("Name", "State", "Autostart", NULL);
+if (!table)
+goto cleanup;
 
 /* Output old style pool info */
 for (i = 0; i < list->npools; i++) {
 const char *name_str = virStoragePoolGet

[libvirt] [PATCH 04/13] virsh: Implement vshTable API to nwfilter-list and nwfilterbinding-list

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-nwfilter.c | 47 +-
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c
index 1cdbe5053a..91e9e78b8b 100644
--- a/tools/virsh-nwfilter.c
+++ b/tools/virsh-nwfilter.c
@@ -31,6 +31,7 @@
 #include "viralloc.h"
 #include "virfile.h"
 #include "virutil.h"
+#include "vsh-table.h"
 
 virNWFilterPtr
 virshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
@@ -359,26 +360,35 @@ cmdNWFilterList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 {
 size_t i;
 char uuid[VIR_UUID_STRING_BUFLEN];
+bool ret = false;
 virshNWFilterListPtr list = NULL;
+vshTablePtr table = NULL;
 
 if (!(list = virshNWFilterListCollect(ctl, 0)))
 return false;
 
-vshPrintExtra(ctl, " %-36s  %-20s \n", _("UUID"), _("Name"));
-vshPrintExtra(ctl, "-"
-   "-\n");
+table = vshTableNew("UUID", "Name", NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nfilters; i++) {
 virNWFilterPtr nwfilter = list->filters[i];
 
 virNWFilterGetUUIDString(nwfilter, uuid);
-vshPrint(ctl, " %-36s  %-20s\n",
- uuid,
- virNWFilterGetName(nwfilter));
+if (vshTableRowAppend(table,
+  uuid,
+  virNWFilterGetName(nwfilter),
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
+ret = true;
+ cleanup:
+vshTableFree(table);
 virshNWFilterListFree(list);
-return true;
+return ret;
 }
 
 /*
@@ -714,25 +724,34 @@ static bool
 cmdNWFilterBindingList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
 {
 size_t i;
+bool ret = false;
 virshNWFilterBindingListPtr list = NULL;
+vshTablePtr table = NULL;
 
 if (!(list = virshNWFilterBindingListCollect(ctl, 0)))
 return false;
 
-vshPrintExtra(ctl, " %-20s  %-20s \n", _("Port Dev"), _("Filter"));
-vshPrintExtra(ctl, "-"
-   "-\n");
+table = vshTableNew("Port Dev", "Filter", NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nbindings; i++) {
 virNWFilterBindingPtr binding = list->bindings[i];
 
-vshPrint(ctl, " %-20s  %-20s\n",
- virNWFilterBindingGetPortDev(binding),
- virNWFilterBindingGetFilterName(binding));
+if (vshTableRowAppend(table,
+  virNWFilterBindingGetPortDev(binding),
+  virNWFilterBindingGetFilterName(binding),
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
+ret = true;
+ cleanup:
+vshTableFree(table);
 virshNWFilterBindingListFree(list);
-return true;
+return ret;
 }
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 10/13] virsh: Implement vshTable API to vcpupin, iothreadinfo, domfsinfo

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain.c | 95 +---
 1 file changed, 71 insertions(+), 24 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c1cff9fe2d..c580be998c 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -59,6 +59,7 @@
 #include "virxml.h"
 #include "virsh-nodedev.h"
 #include "viruri.h"
+#include "vsh-table.h"
 
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
@@ -6905,6 +6906,7 @@ virshVcpuPinQuery(vshControl *ctl,
 size_t i;
 int ncpus;
 bool ret = false;
+vshTablePtr table = NULL;
 
 if ((ncpus = virshCPUCountCollect(ctl, dom, countFlags, true)) < 0) {
 if (ncpus == -1) {
@@ -6913,7 +6915,7 @@ virshVcpuPinQuery(vshControl *ctl,
 else
 vshError(ctl, "%s", _("cannot get vcpupin for transient 
domain"));
 }
-return false;
+goto cleanup;
 }
 
 if (got_vcpu && vcpu >= ncpus) {
@@ -6927,28 +6929,42 @@ virshVcpuPinQuery(vshControl *ctl,
 vshError(ctl,
  _("vcpu %d is out of range of persistent cpu count %d"),
  vcpu, ncpus);
-return false;
+goto cleanup;
 }
 
 cpumaplen = VIR_CPU_MAPLEN(maxcpu);
 cpumap = vshMalloc(ctl, ncpus * cpumaplen);
 if ((ncpus = virDomainGetVcpuPinInfo(dom, ncpus, cpumap,
  cpumaplen, flags)) >= 0) {
-vshPrintExtra(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity"));
-vshPrintExtra(ctl, "--\n");
+table = vshTableNew("VCPU", "CPU Affinity", NULL);
+if (!table)
+goto cleanup;
+
 for (i = 0; i < ncpus; i++) {
+char *pinInfo = NULL;
+char *vcpuStr;
 if (got_vcpu && i != vcpu)
 continue;
 
-vshPrint(ctl, "%4zu: ", i);
-ret = virshPrintPinInfo(ctl, VIR_GET_CPUMAP(cpumap, cpumaplen, i),
-cpumaplen);
-vshPrint(ctl, "\n");
-if (!ret)
-break;
+if (!(pinInfo = virBitmapDataFormat(cpumap, cpumaplen)))
+goto cleanup;
+
+if (virAsprintf(, "%lu", i) < 0)
+goto cleanup;
+
+if (vshTableRowAppend(table, vcpuStr, pinInfo, NULL) < 0)
+goto cleanup;
+
+VIR_FREE(vcpuStr);
+VIR_FREE(pinInfo);
 }
+
+vshTablePrintToStdout(table, ctl);
 }
 
+ret = true;
+ cleanup:
+vshTableFree(table);
 VIR_FREE(cpumap);
 return ret;
 }
@@ -7520,6 +7536,7 @@ cmdIOThreadInfo(vshControl *ctl, const vshCmd *cmd)
 int maxcpu;
 unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
 virshControlPtr priv = ctl->privData;
+vshTablePtr table = NULL;
 
 VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
 VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
@@ -7545,19 +7562,32 @@ cmdIOThreadInfo(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 }
 
-vshPrintExtra(ctl, " %-15s %-15s\n",
-  _("IOThread ID"), _("CPU Affinity"));
-vshPrintExtra(ctl, 
"---\n");
+table = vshTableNew("IOThread ID", "CPU Affinity", NULL);
+if (!table)
+goto cleanup;
+
 for (i = 0; i < niothreads; i++) {
+char *pinInfo = NULL;
+char *iothreadIdStr;
 
-vshPrint(ctl, " %-15u ", info[i]->iothread_id);
-ignore_value(virshPrintPinInfo(ctl, info[i]->cpumap, 
info[i]->cpumaplen));
-vshPrint(ctl, "\n");
+if (virAsprintf(, "%u", info[i]->iothread_id) < 0)
+goto cleanup;
+
+ignore_value(pinInfo = virBitmapDataFormat(info[i]->cpumap, 
info[i]->cpumaplen));
+
+if (vshTableRowAppend(table, iothreadIdStr, pinInfo ? pinInfo : "", 
NULL) < 0)
+goto cleanup;
+
+VIR_FREE(pinInfo);
+VIR_FREE(iothreadIdStr);
 virDomainIOThreadInfoFree(info[i]);
 }
 VIR_FREE(info);
 
+vshTablePrintToStdout(table, ctl);
+
  cleanup:
+vshTableFree(table);
 virshDomainFree(dom);
 return niothreads >= 0;
 }
@@ -13778,6 +13808,7 @@ cmdDomFSInfo(vshControl *ctl, const vshCmd *cmd)
 int ret = -1;
 size_t i, j;
 virDomainFSInfoPtr *info;
+vshTablePtr table = NULL;
 
 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
 return false;
@@ -13793,25 +13824,41 @@ cmdDomFSInfo(vshControl *ctl, const vshCmd *cmd)
 }
 
 if (info) {
-vshPrintExtra(ctl, "%-36s %-8s %-8s %s\n",
-  _(&

[libvirt] [PATCH 05/13] virsh: Implement vshTable API to snapshot-list.

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-snapshot.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index a4ea959230..5a02d2c786 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -41,6 +41,7 @@
 #include "virstring.h"
 #include "virxml.h"
 #include "conf/snapshot_conf.h"
+#include "vsh-table.h"
 
 /* Helper for snapshot-create and snapshot-create-as */
 static bool
@@ -1487,6 +1488,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 char *parent_snap = NULL;
 virDomainSnapshotPtr start = NULL;
 virshSnapshotListPtr snaplist = NULL;
+vshTablePtr table = NULL;
 
 VSH_EXCLUSIVE_OPTIONS_VAR(tree, name);
 VSH_EXCLUSIVE_OPTIONS_VAR(parent, roots);
@@ -1547,15 +1549,12 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 
 if (!tree && !name) {
 if (parent)
-vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
-  _("Name"), _("Creation Time"), _("State"),
-  _("Parent"));
+table = vshTableNew("Name", "Creation Time", "State", "Parent", 
NULL);
 else
-vshPrintExtra(ctl, " %-20s %-25s %s",
-  _("Name"), _("Creation Time"), _("State"));
-vshPrintExtra(ctl, "\n"
-   "--"
-   "--\n");
+table = vshTableNew("Name", "Creation Time", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 if (tree) {
@@ -1614,13 +1613,20 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
  _info);
 
-if (parent)
-vshPrint(ctl, " %-20s %-25s %-15s %s\n",
- snap_name, timestr, state, parent_snap);
-else
-vshPrint(ctl, " %-20s %-25s %s\n", snap_name, timestr, state);
+if (parent) {
+if (vshTableRowAppend(table, snap_name, timestr, state, 
parent_snap,
+  NULL) < 0)
+continue;
+} else {
+if (vshTableRowAppend(table, snap_name, timestr, state,
+  NULL) < 0)
+continue;
+}
 }
 
+if (!tree && !name)
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
@@ -1633,6 +1639,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 xmlFreeDoc(xml);
 VIR_FREE(doc);
 virshDomainFree(dom);
+vshTableFree(table);
 
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 06/13] virsh: Set up cmdDomblkinfo() and cmdDomblkinfoPrint() for vshTable API implementation

2018-09-18 Thread Simon Kobyda
I've moved all the printing from cmdDomblkinfoPrint() to cmdDomblkinfo(),
and renamed the cmdDomblkinfoPrint() to cmdDomblkinfoGet(), since nature of
that function changed from gathering and printing informations only to
gathering information. This I believe simplifies the functions and
makes the implementation of vshTable API simpler.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 78 +---
 1 file changed, 36 insertions(+), 42 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index adc5bb1a7a..cb48f9a7be 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -406,33 +406,23 @@ static const vshCmdOptDef opts_domblkinfo[] = {
 {.name = NULL}
 };
 
-static void
-cmdDomblkinfoPrint(vshControl *ctl,
+static bool
+cmdDomblkinfoGet(vshControl *ctl,
const virDomainBlockInfo *info,
-   const char *device,
-   bool human, bool title)
+   char **cap,
+   char **alloc,
+   char **phy,
+   bool human)
 {
-char *cap = NULL;
-char *alloc = NULL;
-char *phy = NULL;
-
-if (title) {
-vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"),
-  _("Capacity"), _("Allocation"), _("Physical"));
-vshPrintExtra(ctl, "-"
-  "\n");
-return;
-}
-
 if (info->capacity == 0 && info->allocation == 0 && info->physical == 0) {
-cap = vshStrdup(ctl, "-");
-alloc = vshStrdup(ctl, "-");
-phy = vshStrdup(ctl, "-");
+*cap = vshStrdup(ctl, "-");
+*alloc = vshStrdup(ctl, "-");
+*phy = vshStrdup(ctl, "-");
 } else if (!human) {
-if (virAsprintf(, "%llu", info->capacity) < 0 ||
-virAsprintf(, "%llu", info->allocation) < 0 ||
-virAsprintf(, "%llu", info->physical) < 0)
-goto cleanup;
+if (virAsprintf(cap, "%llu", info->capacity) < 0 ||
+virAsprintf(alloc, "%llu", info->allocation) < 0 ||
+virAsprintf(phy, "%llu", info->physical) < 0)
+return false;
 } else {
 double val_cap, val_alloc, val_phy;
 const char *unit_cap, *unit_alloc, *unit_phy;
@@ -441,24 +431,13 @@ cmdDomblkinfoPrint(vshControl *ctl,
 val_alloc = vshPrettyCapacity(info->allocation, _alloc);
 val_phy = vshPrettyCapacity(info->physical, _phy);
 
-if (virAsprintf(, "%.3lf %s", val_cap, unit_cap) < 0 ||
-virAsprintf(, "%.3lf %s", val_alloc, unit_alloc) < 0 ||
-virAsprintf(, "%.3lf %s", val_phy, unit_phy) < 0)
-goto cleanup;
-}
-
-if (device) {
-vshPrint(ctl, "%-10s %-15s %-15s %-15s\n", device, cap, alloc, phy);
-} else {
-vshPrint(ctl, "%-15s %s\n", _("Capacity:"), cap);
-vshPrint(ctl, "%-15s %s\n", _("Allocation:"), alloc);
-vshPrint(ctl, "%-15s %s\n", _("Physical:"), phy);
+if (virAsprintf(cap, "%.3lf %s", val_cap, unit_cap) < 0 ||
+virAsprintf(alloc, "%.3lf %s", val_alloc, unit_alloc) < 0 ||
+virAsprintf(phy, "%.3lf %s", val_phy, unit_phy) < 0)
+return false;
 }
 
- cleanup:
-VIR_FREE(cap);
-VIR_FREE(alloc);
-VIR_FREE(phy);
+return true;
 }
 
 
@@ -478,6 +457,9 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 xmlNodePtr *disks = NULL;
 char *target = NULL;
 char *protocol = NULL;
+char *cap = NULL;
+char *alloc = NULL;
+char *phy = NULL;
 
 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
 return false;
@@ -502,7 +484,10 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 
 /* print the title */
-cmdDomblkinfoPrint(ctl, NULL, NULL, false, true);
+vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"),
+  _("Capacity"), _("Allocation"), _("Physical"));
+vshPrintExtra(ctl, "-"
+  "\n");
 
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
@@ -525,7 +510,9 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
 }
 }
 
-cmdDomblkinfoPrint(ctl, , target, human, false);
+if (!cmdDomblkinfoGet(ctl, , , , , human))
+goto cleanup;
+ 

[libvirt] [PATCH 09/13] virsh: Implement vshTable API to domiflist

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b6739287..d31f02e5e6 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -693,6 +693,7 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 int ninterfaces;
 xmlNodePtr *interfaces = NULL;
 size_t i;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "inactive"))
 flags |= VIR_DOMAIN_XML_INACTIVE;
@@ -704,9 +705,10 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 if (ninterfaces < 0)
 goto cleanup;
 
-vshPrintExtra(ctl, "%-10s %-10s %-10s %-11s %s\n", _("Interface"),
-  _("Type"), _("Source"), _("Model"), _("MAC"));
-vshPrintExtra(ctl, 
"---\n");
+table = vshTableNew("Interface", "Type",
+"Source", "Model", "MAC", NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < ninterfaces; i++) {
 char *type = NULL;
@@ -727,12 +729,14 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 model = virXPathString("string(./model/@type)", ctxt);
 mac = virXPathString("string(./mac/@address)", ctxt);
 
-vshPrint(ctl, "%-10s %-10s %-10s %-11s %-10s\n",
- target ? target : "-",
- type,
- source ? source : "-",
- model ? model : "-",
- mac ? mac : "-");
+if (vshTableRowAppend(table,
+  target ? target : "-",
+  type,
+  source ? source : "-",
+  model ? model : "-",
+  mac ? mac : "-",
+  NULL) < 0)
+goto cleanup;
 
 VIR_FREE(type);
 VIR_FREE(source);
@@ -741,9 +745,12 @@ cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
 VIR_FREE(mac);
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 VIR_FREE(interfaces);
 xmlFreeDoc(xmldoc);
 xmlXPathFreeContext(ctxt);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 08/13] virsh: Implement vshTable API to domblklist

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 05db825716..b9b6739287 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -589,6 +589,7 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 char *device = NULL;
 char *target = NULL;
 char *source = NULL;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "inactive"))
 flags |= VIR_DOMAIN_XML_INACTIVE;
@@ -603,12 +604,12 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 
 if (details)
-vshPrintExtra(ctl, "%-10s %-10s %-10s %s\n", _("Type"),
-  _("Device"), _("Target"), _("Source"));
+table = vshTableNew("Type", "Device", "Target", "Source", NULL);
 else
-vshPrintExtra(ctl, "%-10s %s\n", _("Target"), _("Source"));
+table = vshTableNew("Target", "Source", NULL);
 
-vshPrintExtra(ctl, "\n");
+if (!table)
+goto cleanup;
 
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
@@ -633,10 +634,13 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 "|./source/@name"
 "|./source/@volume)", ctxt);
 if (details) {
-vshPrint(ctl, "%-10s %-10s %-10s %s\n", type, device,
- target, source ? source : "-");
+if (vshTableRowAppend(table, type, device, target,
+  source ? source : "-", NULL) < 0)
+goto cleanup;
 } else {
-vshPrint(ctl, "%-10s %s\n", target, source ? source : "-");
+if (vshTableRowAppend(table, target,
+  source ? source : "-", NULL) < 0)
+goto cleanup;
 }
 
 VIR_FREE(source);
@@ -645,9 +649,12 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 VIR_FREE(type);
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 VIR_FREE(source);
 VIR_FREE(target);
 VIR_FREE(device);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 03/13] virsh: Implement vshTable API to secret-list

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-secret.c | 30 ++
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index 670beea706..0ae248b4dd 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -35,6 +35,7 @@
 #include "virsecret.h"
 #include "virstring.h"
 #include "virtime.h"
+#include "vsh-table.h"
 
 static virSecretPtr
 virshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name)
@@ -507,6 +508,7 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 virshSecretListPtr list = NULL;
 bool ret = false;
 unsigned int flags = 0;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "ephemeral"))
 flags |= VIR_CONNECT_LIST_SECRETS_EPHEMERAL;
@@ -523,15 +525,17 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 if (!(list = virshSecretListCollect(ctl, flags)))
 return false;
 
-vshPrintExtra(ctl, " %-36s  %s\n", _("UUID"), _("Usage"));
-vshPrintExtra(ctl, ""
-   "\n");
+table = vshTableNew("UUID", "Usage", NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nsecrets; i++) {
 virSecretPtr sec = list->secrets[i];
 int usageType = virSecretGetUsageType(sec);
 const char *usageStr = virSecretUsageTypeToString(usageType);
 char uuid[VIR_UUID_STRING_BUFLEN];
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+const char *usage;
 
 if (virSecretGetUUIDString(sec, uuid) < 0) {
 vshError(ctl, "%s", _("Failed to get uuid of secret"));
@@ -539,18 +543,28 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 }
 
 if (usageType) {
-vshPrint(ctl, " %-36s  %s %s\n",
- uuid, usageStr,
- virSecretGetUsageID(sec));
+virBufferStrcat(, usageStr, " ",
+virSecretGetUsageID(sec), NULL);
+usage = virBufferCurrentContent();
+if (!usage)
+goto cleanup;
+
+if (vshTableRowAppend(table, uuid, usage, NULL) < 0)
+goto cleanup;
+
+virBufferFreeAndReset();
 } else {
-vshPrint(ctl, " %-36s  %s\n",
- uuid, _("Unused"));
+if (vshTableRowAppend(table, uuid, "Unused", NULL) < 0)
+goto cleanup;
 }
 }
 
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
 
  cleanup:
+vshTableFree(table);
 virshSecretListFree(list);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 02/13] virsh: Implement vshTable API to net-list and net-dhcp-leases

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-network.c | 55 +--
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index ca07fb568f..0f975b8899 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -33,6 +33,7 @@
 #include "virstring.h"
 #include "virtime.h"
 #include "conf/network_conf.h"
+#include "vsh-table.h"
 
 #define VIRSH_COMMON_OPT_NETWORK(_helpstr, cflags) \
 {.name = "network", \
@@ -677,6 +678,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 bool optUUID = vshCommandOptBool(cmd, "uuid");
 char uuid[VIR_UUID_STRING_BUFLEN];
 unsigned int flags = VIR_CONNECT_LIST_NETWORKS_ACTIVE;
+vshTablePtr table = NULL;
 
 if (vshCommandOptBool(cmd, "inactive"))
 flags = VIR_CONNECT_LIST_NETWORKS_INACTIVE;
@@ -705,10 +707,10 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 return false;
 
 if (optTable) {
-vshPrintExtra(ctl, " %-20s %-10s %-13s %s\n", _("Name"), _("State"),
-  _("Autostart"), _("Persistent"));
-vshPrintExtra(ctl,
-  
"--\n");
+table = vshTableNew("Name", "State", "Autostart",
+"Persistent", NULL);
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->nnets; i++) {
@@ -722,11 +724,15 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 else
 autostartStr = is_autostart ? _("yes") : _("no");
 
-vshPrint(ctl, " %-20s %-10s %-13s %s\n",
- virNetworkGetName(network),
- virNetworkIsActive(network) ? _("active") : _("inactive"),
- autostartStr,
- virNetworkIsPersistent(network) ? _("yes") : _("no"));
+if (vshTableRowAppend(table,
+  virNetworkGetName(network),
+  virNetworkIsActive(network) ?
+  _("active") : _("inactive"),
+  autostartStr,
+  virNetworkIsPersistent(network) ?
+  _("yes") : _("no"),
+  NULL) < 0)
+goto cleanup;
 } else if (optUUID) {
 if (virNetworkGetUUIDString(network, uuid) < 0) {
 vshError(ctl, "%s", _("Failed to get network's UUID"));
@@ -738,8 +744,12 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 }
 }
 
+if (optTable)
+vshTablePrintToStdout(table, ctl);
+
 ret = true;
  cleanup:
+vshTableFree(table);
 virshNetworkListFree(list);
 return ret;
 }
@@ -1351,6 +1361,7 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 size_t i;
 unsigned int flags = 0;
 virNetworkPtr network = NULL;
+vshTablePtr table = NULL;
 
 if (vshCommandOptStringReq(ctl, cmd, "mac", ) < 0)
 return false;
@@ -1366,11 +1377,11 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 /* Sort the list according to MAC Address/IAID */
 qsort(leases, nleases, sizeof(*leases), virshNetworkDHCPLeaseSorter);
 
-vshPrintExtra(ctl, " %-20s %-18s %-9s %-25s %-15s %s\n%s%s\n",
-  _("Expiry Time"), _("MAC address"), _("Protocol"),
-  _("IP address"), _("Hostname"), _("Client ID or DUID"),
-  "--",
-  "-");
+table = vshTableNew("Expiry Time", "MAC address", "Protocol",
+"IP address", "Hostname", "Client ID or DUID",
+NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < nleases; i++) {
 const char *typestr = NULL;
@@ -1390,17 +1401,25 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 ignore_value(virAsprintf(_format, "%s/%d",
  lease->ipaddr, lease->prefix));
 
-vshPrint(ctl, " %-20s %-18s %-9s %-25s %-15s %s\n",
- expirytime, EMPTYSTR(lease->mac),
- EMPTYSTR(typestr), cidr_format,
- EMPTYSTR(lease->hostname), EMPTYSTR(lease->clientid));
+if (

[libvirt] [PATCH 00/13] Implement vsh-table API to virsh and virt-admin

2018-09-18 Thread Simon Kobyda
API is implemented in virsh and virt-admin. It fixes problems with
table-alignment, makes tables more readable and deals with unicode.
Table however could not be implemented in places, which do use simple
lists, or table implementation would change content of output,
which users might rely on.
If you know about other place where it could be implemented,
let me know.

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Simon Kobyda (13):
  virsh: Implement vsh-table to iface-list
  virsh: Implement vshTable API to net-list and net-dhcp-leases
  virsh: Implement vshTable API to secret-list
  virsh: Implement vshTable API to nwfilter-list and
nwfilterbinding-list
  virsh: Implement vshTable API to snapshot-list.
  virsh: Set up cmdDomblkinfo() and cmdDomblkinfoPrint() for vshTable
API implementation
  virsh: Implement vshTable API to domblkinfo
  virsh: Implement vshTable API to domblklist
  virsh: Implement vshTable API to domiflist
  virsh: Implement vshTable API to vcpupin, iothreadinfo, domfsinfo
  virsh: Implement vshTable API to pool-list
  virsh: Implement vshTable API to vol-list
  virt-admin: Implement vshTable API to server-list and client-list

 tools/virsh-domain-monitor.c | 131 +++-
 tools/virsh-domain.c |  95 +++--
 tools/virsh-interface.c  |  27 --
 tools/virsh-network.c|  55 
 tools/virsh-nwfilter.c   |  47 +++---
 tools/virsh-pool.c   | 160 +++
 tools/virsh-secret.c |  30 +--
 tools/virsh-snapshot.c   |  33 +---
 tools/virsh-volume.c | 127 ++-
 tools/virt-admin.c   |  46 +++---
 10 files changed, 367 insertions(+), 384 deletions(-)

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 01/13] virsh: Implement vsh-table to iface-list

2018-09-18 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 
---
 tools/virsh-interface.c | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/tools/virsh-interface.c b/tools/virsh-interface.c
index 50518c667b..3234845596 100644
--- a/tools/virsh-interface.c
+++ b/tools/virsh-interface.c
@@ -48,6 +48,7 @@
 #include "virutil.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 virInterfacePtr
 virshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
@@ -356,6 +357,8 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 unsigned int flags = VIR_CONNECT_LIST_INTERFACES_ACTIVE;
 virshInterfaceListPtr list = NULL;
 size_t i;
+bool ret = false;
+vshTablePtr table = NULL;
 
 if (inactive)
 flags = VIR_CONNECT_LIST_INTERFACES_INACTIVE;
@@ -366,21 +369,29 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd 
ATTRIBUTE_UNUSED)
 if (!(list = virshInterfaceListCollect(ctl, flags)))
 return false;
 
-vshPrintExtra(ctl, " %-20s %-10s %s\n", _("Name"), _("State"),
-  _("MAC Address"));
-vshPrintExtra(ctl, 
"---\n");
+table = vshTableNew("Name", "State", "MAC Address", NULL);
+if (!table)
+goto cleanup;
 
 for (i = 0; i < list->nifaces; i++) {
 virInterfacePtr iface = list->ifaces[i];
 
-vshPrint(ctl, " %-20s %-10s %s\n",
- virInterfaceGetName(iface),
- virInterfaceIsActive(iface) ? _("active") : _("inactive"),
- virInterfaceGetMACString(iface));
+if (vshTableRowAppend(table,
+  virInterfaceGetName(iface),
+  virInterfaceIsActive(iface) ? _("active")
+  : _("inactive"),
+  virInterfaceGetMACString(iface),
+  NULL) < 0)
+goto cleanup;
 }
 
+vshTablePrintToStdout(table, ctl);
+
+ret = true;
+ cleanup:
+vshTableFree(table);
 virshInterfaceListFree(list);
-return true;
+return ret;
 }
 
 /*
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] tests: skip some unicode tests if expected output won't match

2018-09-04 Thread Simon Kobyda
On Tue, 2018-09-04 at 11:30 +0100, Daniel P. Berrangé wrote:
> The expected output strings from the vshtabletest.c are created on a
> modern Linux host where unicode printing support is very good. On
> older
> Linux platforms, or non-Linux platforms, some unicode characters will
> not be considered printable. While the vsh table alignment code will
> stil do the right thing with escaping & aligning in this case, the
> result will not match the test's expected output.
> 
> Since we know the code is working correctly, do a check with
> iswprint()
> to validate the platform's quality and skip the test if it fails.
> This
> fixes the test on FreeBSD platforms.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
> 
> Pushed as a build fix
> 
>  tests/vshtabletest.c | 19 +++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
> index 9e9c045226..1138e34161 100644
> --- a/tests/vshtabletest.c
> +++ b/tests/vshtabletest.c
> @@ -21,6 +21,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "internal.h"
>  #include "testutils.h"
> @@ -158,6 +159,15 @@ testUnicodeArabic(const void *opaque
> ATTRIBUTE_UNUSED)
>  " 1  ﻉﺪﻴﻟ ﺎﻠﺜﻘﻴﻟ ﻕﺎﻣ ﻊﻧ, ٣٠ ﻎﻴﻨﻳﺍ ﻮﺘﻧﺎﻤﺗ ﺎﻠﺛﺎﻠﺛ، ﺄﺳﺭ,
> ﺩﻮﻟ   ﺩﻮﻟ. ﺄﻣﺎﻣ ﺍ ﺎﻧ ﻲﻜﻧ  \n"
>  " ﺺﻔﺣﺓ   ﺖﻜﺘﻴﻛﺍً ﻊﻟ, ﺎﻠﺠﻧﻭﺩ
> ﻭﺎﻠﻌﺗﺍﺩ  ﺵﺭ  \n";
>  vshTablePtr table;
> +wchar_t wc;
> +
> +/* If this char is not classed as printable, the actual
> + * output won't match what this test expects. The code
> + * is still operating correctly, but we have different
> + * layout */
> +mbrtowc(, "،", MB_CUR_MAX, NULL);
> +if (!iswprint(wc))
> +return EXIT_AM_SKIP;
>  
>  table = vshTableNew("ﻡﺍ ﻢﻣﺍ ﻕﺎﺌﻣﺓ", "ﺓ ﺎﻠﺼﻋ", "ﺍﻸﺜﻧﺎﻧ", NULL);
>  if (!table)
> @@ -192,6 +202,15 @@ testUnicodeZeroWidthChar(const void *opaque
> ATTRIBUTE_UNUSED)
>  " 1\u200Bfedora28   run\u200Bning  \n"
>  " 2rhel7.5running  \n";
>  char *act = NULL;
> +wchar_t wc;
> +
> +/* If this char is not classed as printable, the actual
> + * output won't match what this test expects. The code
> + * is still operating correctly, but we have different
> + * layout */
> +mbrtowc(, "\u200B", MB_CUR_MAX, NULL);
> +if (!iswprint(wc))
> +return EXIT_AM_SKIP;

Sidenote: This test case with zero-width characters would pass without
any problems if we implement environment variable
"gl_cv_func_wcwidth_works=no" as suggested here: 
https://lists.gnu.org/archive/html/bug-gnulib/2018-08/msg00165.html.
But that's not something important.
I'm happy that tests on freebsd pass :).

Simon.

>  
>  table = vshTableNew("I\u200Bd", "Name", "\u200BStatus", NULL);
>  if (!table)

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH] vsh-table: Fix broken build on centos and rhel

2018-08-29 Thread Simon Kobyda
The reason of broken build was that centos and rhel use older version of glibc.
These versions of glibc on these platforms cannot work with newer unicodes,
therefore functions iswprint() and wcwidth() failed. So I replaced them with
older unicode characters.

Signed-off-by: Simon Kobyda 
---
 tests/vshtabletest.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
index 1b07c37c56..9e9c045226 100644
--- a/tests/vshtabletest.c
+++ b/tests/vshtabletest.c
@@ -123,7 +123,7 @@ testUnicode(const void *opaque ATTRIBUTE_UNUSED)
 " Id   名稱  государство  \n"
 "-\n"
 " 1fedora28  running  \n"
-" 2rhel7.5   running  \n";
+" 2つへソrhel7.5つへソ   running  \n";
 vshTablePtr table;
 
 table = vshTableNew("Id", "名稱", "государство", NULL);
@@ -131,7 +131,7 @@ testUnicode(const void *opaque ATTRIBUTE_UNUSED)
 goto cleanup;
 
 vshTableRowAppend(table, "1", "fedora28", "running", NULL);
-vshTableRowAppend(table, "2", "rhel7.5", "running",
+vshTableRowAppend(table, "2", "つへソrhel7.5つへソ", "running",
   NULL);
 
 act = vshTablePrintToString(table, true);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v5 0/3] vsh: Introduce new API for printing tables

2018-08-28 Thread Simon Kobyda
On Tue, 2018-08-28 at 14:35 +0200, Simon Kobyda wrote:
> CentOS 7 uses
> glibc 2.17, which was released in December 2017

Sorry made a typo there, glibc 2.17 was released in 2012

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v5 0/3] vsh: Introduce new API for printing tables

2018-08-28 Thread Simon Kobyda
On Fri, 2018-08-24 at 11:18 +0100, Daniel P. Berrangé wrote:
> On Fri, Aug 24, 2018 at 12:10:47PM +0200, Michal Privoznik wrote:
> > On 08/24/2018 11:36 AM, Daniel P. Berrangé wrote:
> > > On Fri, Aug 24, 2018 at 10:59:04AM +0200, Michal Privoznik wrote:
> > > > On 08/23/2018 05:53 PM, Simon Kobyda wrote:
> > > > > Created new API for priting tables, mainly to solve alignment
> > > > > problems.
> > > > > Implemented these test to virsh list. In the future, API may
> > > > > be
> > > > > everywhere in virsh and virt-admin.
> > > > > Also wrote basic tests for the new API, and corrected tests
> > > > > in virshtest
> > > > > which are influenced by implementation of the API in virsh
> > > > > list.
> > > > > 
> > > > > Changes in v5:
> > > > > - cleanup and merged code for calculating zero-width,
> > > > > nonprintable and combined
> > > > > character.
> > > > > - replaced virBufferAddStr with virBufferAddChar in some
> > > > > places
> > > > > - in tests moved code for setting correct locale
> > > > > - fixed few leaks and unitialized values
> > > > > 
> > > > > Changes in v4:
> > > > > - fixed width calculation for zero-width, nonprintable and
> > > > > combined
> > > > > character. (pulled some code from linux-util)
> > > > > - added tests for cases mentioned above
> > > > > - changed usage of vshControl variables. From now on
> > > > > PrintToStdout calls
> > > > > PrintToString and then prints returned string to stdout
> > > > > 
> > > > > Changes in v3:
> > > > > - changed encoding of 3/3 patch, otherwise it cannot be
> > > > > applied
> > > > > 
> > > > > Changes in v2:
> > > > > - added tests
> > > > > - fixed alignment for unicode character which span more
> > > > > spaces
> > > > > - moved ncolumns check to vshTableRowAppend
> > > > > - changed arguments for functions vshTablePrint,
> > > > > vshTablePrintToStdout,
> > > > > vshTablePrintToString
> > > > > 
> > > > > Simon Kobyda (3):
> > > > >   vsh: Add API for printing tables.
> > > > >   virsh: Implement new table API for virsh list
> > > > >   vsh: Added tests
> > > > > 
> > > > >  tests/Makefile.am|   8 +
> > > > >  tests/virshtest.c|  14 +-
> > > > >  tests/vshtabletest.c | 377
> > > > > +
> > > > >  tools/Makefile.am|   4 +-
> > > > >  tools/virsh-domain-monitor.c |  43 ++--
> > > > >  tools/vsh-table.c| 449
> > > > > +++
> > > > >  tools/vsh-table.h|  42 
> > > > >  7 files changed, 910 insertions(+), 27 deletions(-)
> > > > >  create mode 100644 tests/vshtabletest.c
> > > > >  create mode 100644 tools/vsh-table.c
> > > > >  create mode 100644 tools/vsh-table.h
> > > > > 
> > > > 
> > > > ACKed and pushed.
> > > > 
> > > > Now we can start converting the rest of the code to use
> > > > vshTable APIs.
> > > 
> > > But first fix the build failures :-)
> > > 
> > > On CentOS / RHEL:
> > > 
> > > https://travis-ci.org/libvirt/libvirt/jobs/420024141
> > > 
> > > 
> > >  4)
> > > testUnicode  
> > >  ... 
> > > Offset 30
> > > Expect [государство  
> > > -
> > >  1fedora28  running  
> > >  2rhel7.5]
> > > Actual
> > > [
> > > государство  
> > > ---
> > > --
> > >  1fedora28   
> > >running  
> > >  2\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffrhel7.5\xff
> > > \xff\xff\xff\xff\xff\xf

Re: [libvirt] [PATCH v5 0/3] vsh: Introduce new API for printing tables

2018-08-27 Thread Simon Kobyda
On Fri, 2018-08-24 at 12:10 +0200, Michal Privoznik wrote:
> On 08/24/2018 11:36 AM, Daniel P. Berrangé wrote:
> > On Fri, Aug 24, 2018 at 10:59:04AM +0200, Michal Privoznik wrote:
> > 
> > But first fix the build failures :-)
> > 
> > On CentOS / RHEL:
> > 
> > https://travis-ci.org/libvirt/libvirt/jobs/420024141
> > 
> > 
> >  4)
> > testUnicode   .
> > .. 
> > Offset 30
> > Expect [государство  
> > -
> >  1fedora28  running  
> >  2rhel7.5]
> > Actual
> > [  
> >   государство  
> > -
> > 
> >  1fedora28 
> >  running  
> >  2\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffrhel7.5\xff\x
> > ff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff]
> > 
> 
> Okay, this is probably due to ancient gcc that's there (4.8.0) and is
> supposed to be fixed by adding -finput-charset= onto gcc command
> line.
> Haven't tested it though.

I tried but it didn't help. From what I understood, CentOS has problems
with unicodes such as . On that system, it can convert 
any of those characters to wchar_t successfully and properly, but when
we pass that character to iswprint, it returns 0 (considers those wide
characters nonprintable).

Simon Kobyda

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH] vsh: Fix broken build on mingw

2018-08-27 Thread Simon Kobyda
The function wcwidth() doesn't exist on mingw. However we can
implement this function from gnulib.
Broken gnulib on CentOS and RHEL still persists.

Signed-off-by: Simon Kobyda 
---
 bootstrap.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bootstrap.conf b/bootstrap.conf
index 698a52216b..d9e2b0662c 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -126,6 +126,7 @@ vc-list-files
 vsnprintf
 waitpid
 warnings
+wcwidth
 '
 
 SKIP_PO=true
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 2/3] virsh: Implement new table API for virsh list

2018-08-23 Thread Simon Kobyda
Instead of printing it straight in virsh, it creates table struct
which is filled with header and rows(domains). It allows us to know
more about table before printing to calculate alignment right.

Signed-off-by: Simon Kobyda 
---
 tests/virshtest.c| 14 ++--
 tools/virsh-domain-monitor.c | 43 
 2 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/tests/virshtest.c b/tests/virshtest.c
index 94548a82d1..10cd0d356b 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -98,9 +98,9 @@ static int testCompareListDefault(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_DEFAULT, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 test   running\n\
+ Id   Name   State\n\
+--\n\
+ 1test   running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
@@ -109,10 +109,10 @@ static int testCompareListCustom(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_CUSTOM, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 fv0running\n\
- 2 fc4running\n\
+ Id   Name   State\n\
+--\n\
+ 1fv0running  \n\
+ 2fc4running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b4f9739b..adc5bb1a7a 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -39,6 +39,7 @@
 #include "virmacaddr.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 VIR_ENUM_DECL(virshDomainIOError)
 VIR_ENUM_IMPL(virshDomainIOError,
@@ -1901,6 +1902,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
 unsigned int id;
 unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+vshTablePtr table = NULL;
 
 /* construct filter flags */
 if (vshCommandOptBool(cmd, "inactive") ||
@@ -1940,15 +1942,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 /* print table header in legacy mode */
 if (optTable) {
 if (optTitle)
-vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
-  _("Id"), _("Name"), _("State"), _("Title"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Name", "State", "Title", NULL);
 else
-vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
-  _("Id"), _("Name"), _("State"),
-  "-"
-  "---");
+table = vshTableNew("Id", "Name", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->ndomains; i++) {
@@ -1973,20 +1972,22 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 if (optTitle) {
 if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
 goto cleanup;
-
-vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state),
- title);
-
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  title, NULL) < 0)
+goto cleanup;
 VIR_FREE(title);
 } else {
-vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state));
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  NULL) < 0)
+goto cleanup;
 }
+
 } el

[libvirt] [PATCH v5 0/3] vsh: Introduce new API for printing tables

2018-08-23 Thread Simon Kobyda
Created new API for priting tables, mainly to solve alignment problems.
Implemented these test to virsh list. In the future, API may be
everywhere in virsh and virt-admin.
Also wrote basic tests for the new API, and corrected tests in virshtest
which are influenced by implementation of the API in virsh list.

Changes in v5:
- cleanup and merged code for calculating zero-width, nonprintable and combined
character.
- replaced virBufferAddStr with virBufferAddChar in some places
- in tests moved code for setting correct locale
- fixed few leaks and unitialized values

Changes in v4:
- fixed width calculation for zero-width, nonprintable and combined
character. (pulled some code from linux-util)
- added tests for cases mentioned above
- changed usage of vshControl variables. From now on PrintToStdout calls
PrintToString and then prints returned string to stdout

Changes in v3:
- changed encoding of 3/3 patch, otherwise it cannot be applied

Changes in v2:
- added tests
- fixed alignment for unicode character which span more spaces
- moved ncolumns check to vshTableRowAppend
- changed arguments for functions vshTablePrint, vshTablePrintToStdout,
vshTablePrintToString

Simon Kobyda (3):
  vsh: Add API for printing tables.
  virsh: Implement new table API for virsh list
  vsh: Added tests

 tests/Makefile.am|   8 +
 tests/virshtest.c|  14 +-
 tests/vshtabletest.c | 377 +
 tools/Makefile.am|   4 +-
 tools/virsh-domain-monitor.c |  43 ++--
 tools/vsh-table.c| 449 +++
 tools/vsh-table.h|  42 
 7 files changed, 910 insertions(+), 27 deletions(-)
 create mode 100644 tests/vshtabletest.c
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 1/3] vsh: Add API for printing tables.

2018-08-23 Thread Simon Kobyda
It solves problems with alignment of columns. Width of each column
is calculated by its biggest cell. Should solve unicode bug.
In future, it may be implemented in virsh, virt-admin...

This API has 5 public functions:
- vshTableNew - adds new table and defines its header
- vshTableRowAppend - appends new row (for same number of columns as in
header)
- vshTablePrintToStdout
- vshTablePrintToString
- vshTableFree

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Signed-off-by: Simon Kobyda 
---
 tools/Makefile.am |   4 +-
 tools/vsh-table.c | 449 ++
 tools/vsh-table.h |  42 +
 3 files changed, 494 insertions(+), 1 deletion(-)
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 1452d984a0..f069167acc 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
$(READLINE_LIBS) \
../gnulib/lib/libgnu.la \
$(NULL)
-libvirt_shell_la_SOURCES = vsh.c vsh.h
+libvirt_shell_la_SOURCES = \
+   vsh.c vsh.h \
+   vsh-table.c vsh-table.h
 
 virt_host_validate_SOURCES = \
virt-host-validate.c \
diff --git a/tools/vsh-table.c b/tools/vsh-table.c
new file mode 100644
index 00..ca4e9265c5
--- /dev/null
+++ b/tools/vsh-table.c
@@ -0,0 +1,449 @@
+/*
+ * vsh-table.c: table printing helper
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Simon Kobyda 
+ *
+ */
+
+#include 
+#include "vsh-table.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "c-ctype.h"
+
+#include "viralloc.h"
+#include "virbuffer.h"
+#include "virstring.h"
+#include "virsh-util.h"
+
+#define HEX_ENCODE_LENGTH 4 /* represents length of '\xNN' */
+
+struct _vshTableRow {
+char **cells;
+size_t ncells;
+};
+
+struct _vshTable {
+vshTableRowPtr *rows;
+size_t nrows;
+};
+
+static void
+vshTableRowFree(vshTableRowPtr row)
+{
+size_t i;
+
+if (!row)
+return;
+
+for (i = 0; i < row->ncells; i++)
+VIR_FREE(row->cells[i]);
+
+VIR_FREE(row->cells);
+VIR_FREE(row);
+}
+
+void
+vshTableFree(vshTablePtr table)
+{
+size_t i;
+
+if (!table)
+return;
+
+for (i = 0; i < table->nrows; i++)
+vshTableRowFree(table->rows[i]);
+VIR_FREE(table->rows);
+VIR_FREE(table);
+}
+
+/**
+ * vshTableRowNew:
+ * @arg: the first argument.
+ * @ap: list of variadic arguments
+ *
+ * Create a new row in the table. Each argument passed
+ * represents a cell in the row.
+ *
+ * Return: pointer to vshTableRowPtr row or NULL.
+ */
+static vshTableRowPtr
+vshTableRowNew(const char *arg, va_list ap)
+{
+vshTableRowPtr row = NULL;
+
+if (!arg) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Table row cannot be empty"));
+goto error;
+}
+
+if (VIR_ALLOC(row) < 0)
+goto error;
+
+while (arg) {
+char *tmp = NULL;
+
+if (VIR_STRDUP(tmp, arg) < 0)
+goto error;
+
+if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0) {
+VIR_FREE(tmp);
+goto error;
+}
+
+arg = va_arg(ap, const char *);
+}
+
+return row;
+
+ error:
+vshTableRowFree(row);
+return NULL;
+}
+
+/**
+ * vshTableNew:
+ * @arg: List of column names (NULL terminated)
+ *
+ * Create a new table.
+ *
+ * Returns: pointer to table or NULL.
+ */
+vshTablePtr
+vshTableNew(const char *arg, ...)
+{
+vshTablePtr table = NULL;
+vshTableRowPtr header = NULL;
+va_list ap;
+
+if (VIR_ALLOC(table) < 0)
+goto error;
+
+va_start(ap, arg);
+header = vshTableRowNew(arg, ap);
+va_end(ap);
+
+if (!header)
+goto error;
+
+if (VIR_APPEND_ELEMENT(table->rows, table->nrows, header) < 0)
+goto error;
+
+return table;
+ error:
+vshTableRowFree(header);
+vshTableFree(table);
+return NULL;
+}
+
+/**
+ * vshTableRowAppend:
+ * @table: table to append to
+ * @arg: cells of the row (NULL t

[libvirt] [PATCH v5 3/3] vsh: Added tests

2018-08-23 Thread Simon Kobyda
For now, there are 9 test cases
- testVshTableNew: Creating table with empty header
- testVshTableHeader: Printing table with/without header
- testVshTableRowAppend: Appending row with various number of cells.
  Only row with same number of cells as in header is accepted.
- testUnicode: Printing table with unicode characters.
  Checking correct alignment.
- testUnicodeArabic: test opposite (right to left) writing
- testUnicodeZeroWidthChar
- testUnicodeCombiningChar
- testUnicodeNonPrintableChar,
- testNTables: Create and print varios types of tables - one column,
  one row table, table without content, standart table...

Signed-off-by: Simon Kobyda 
---
 tests/Makefile.am|   8 +
 tests/vshtabletest.c | 377 +++
 2 files changed, 385 insertions(+)
 create mode 100644 tests/vshtabletest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 21a6c823d9..136fe16f71 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ test_programs = virshtest sockettest \
virhostdevtest \
virnetdevtest \
virtypedparamtest \
+   vshtabletest \
$(NULL)
 
 test_libraries = libshunload.la \
@@ -938,6 +939,13 @@ metadatatest_SOURCES = \
testutils.c testutils.h
 metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
 
+vshtabletest_SOURCES = \
+   vshtabletest.c \
+   testutils.c testutils.h
+vshtabletest_LDADD = \
+   $(LDADDS) \
+   ../tools/libvirt_shell.la
+
 virshtest_SOURCES = \
virshtest.c \
testutils.c testutils.h
diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
new file mode 100644
index 00..1b07c37c56
--- /dev/null
+++ b/tests/vshtabletest.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include "testutils.h"
+#include "viralloc.h"
+#include "../tools/vsh-table.h"
+
+static int
+testVshTableNew(const void *opaque ATTRIBUTE_UNUSED)
+{
+if (vshTableNew(NULL)) {
+fprintf(stderr, "expected failure when passing null to vshTableNew\n");
+return -1;
+}
+
+return 0;
+}
+
+static int
+testVshTableHeader(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+char *act = NULL;
+const char *exp =
+" 1   fedora28   running  \n"
+" 2   rhel7.5running  \n";
+const char *exp2 =
+" Id   Name   State\n"
+"--\n"
+" 1fedora28   running  \n"
+" 2rhel7.5running  \n";
+
+vshTablePtr table = vshTableNew("Id", "Name", "State",
+NULL); //to ask about return
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+act = vshTablePrintToString(table, false);
+if (virTestCompareToString(exp, act) < 0)
+ret = -1;
+
+VIR_FREE(act);
+act = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp2, act) < 0)
+ret = -1;
+
+ cleanup:
+VIR_FREE(act);
+vshTableFree(table);
+return ret;
+}
+
+static int
+testVshTableRowAppend(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+
+vshTablePtr table = vshTableNew("Id", "Name", NULL);
+if (!table)
+goto cleanup;
+
+if (vshTableRowAppend(table, NULL) >= 0) {
+fprintf(stderr, "Appending NULL shouldn't work\n");
+ret = -1;
+}
+
+if (vshTableRowAppend(table, "2", NULL) >= 0) {
+fprintf(stderr, "Appending less items than in header\n");
+ret = -1;
+}
+
+if (vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL) >= 0) {
+fprintf(stderr, "Appending more items than in header\n");
+ret = -1;
+}
+
+if (vshTableRowAppend(table, "2", "rhel7.5", NULL) < 0) {
+fprintf(stderr, "Appending same number of

Re: [libvirt] [PATCH v4 1/3] vsh: Add API for printing tables.

2018-08-23 Thread Simon Kobyda
On Thu, 2018-08-23 at 15:19 +0200, Michal Privoznik wrote:
> NB, do we need to re-encode the string? All that we care about is its
> width, isn't it?

Yes. Many nonprintable or control characters such as tabulator,
vertical tabulator, backspace... would be problematic, especially when
calculating width. So its better to just replace them with their
hexadecimal value.

Simon Kobyda

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v4 1/3] vsh: Add API for printing tables.

2018-08-23 Thread Simon Kobyda
On Wed, 2018-08-22 at 19:42 +0200, Simon Kobyda wrote:
> It solves problems with alignment of columns. Width of each column
> is calculated by its biggest cell. Should solve unicode bug.
> In future, it may be implemented in virsh, virt-admin...
> 
> This API has 5 public functions:
> - vshTableNew - adds new table and defines its header
> - vshTableRowAppend - appends new row (for same number of columns as
> in
> header)
> - vshTablePrintToStdout
> - vshTablePrintToString
> - vshTableFree
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1574624
> https://bugzilla.redhat.com/show_bug.cgi?id=1584630
> 
> Signed-off-by: Simon Kobyda 
> ---
>  tools/Makefile.am |   4 +-
>  tools/vsh-table.c | 483
> ++
>  tools/vsh-table.h |  42 
>  3 files changed, 528 insertions(+), 1 deletion(-)
>  create mode 100644 tools/vsh-table.c
>  create mode 100644 tools/vsh-table.h
> 
> diff --git a/tools/Makefile.am b/tools/Makefile.am
> index 1452d984a0..f069167acc 100644
> --- a/tools/Makefile.am
> +++ b/tools/Makefile.am
> @@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
>   $(READLINE_LIBS) \
>   ../gnulib/lib/libgnu.la \
>   $(NULL)
> -libvirt_shell_la_SOURCES = vsh.c vsh.h
> +libvirt_shell_la_SOURCES = \
> + vsh.c vsh.h \
> + vsh-table.c vsh-table.h
>  
>  virt_host_validate_SOURCES = \
>   virt-host-validate.c \
> diff --git a/tools/vsh-table.c b/tools/vsh-table.c
> new file mode 100644
> index 00..6e1793e4e3
> --- /dev/null
> +++ b/tools/vsh-table.c
> @@ -0,0 +1,483 @@
> +/*
> + * vsh-table.c: table printing helper
> + *
> + * Copyright (C) 2018 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later
> version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Authors:
> + *   Simon Kobyda 
> + *
> + */
> +
> +#include 
> +#include "vsh-table.h"
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "c-ctype.h"
> +
> +#include "viralloc.h"
> +#include "virbuffer.h"
> +#include "virstring.h"
> +#include "virsh-util.h"
> +
> +#define HEX_ENCODE_LENGTH 4 /* represents length of '\xNN' */
> +
> +struct _vshTableRow {
> +char **cells;
> +size_t ncells;
> +};
> +
> +struct _vshTable {
> +vshTableRowPtr *rows;
> +size_t nrows;
> +};
> +
> +static void
> +vshTableRowFree(vshTableRowPtr row)
> +{
> +size_t i;
> +
> +if (!row)
> +return;
> +
> +for (i = 0; i < row->ncells; i++)
> +VIR_FREE(row->cells[i]);
> +
> +VIR_FREE(row->cells);
> +VIR_FREE(row);
> +}
> +
> +void
> +vshTableFree(vshTablePtr table)
> +{
> +size_t i;
> +
> +if (!table)
> +return;
> +
> +for (i = 0; i < table->nrows; i++)
> +vshTableRowFree(table->rows[i]);
> +VIR_FREE(table->rows);
> +VIR_FREE(table);
> +}
> +
> +/**
> + * vshTableRowNew:
> + * @arg: the first argument.
> + * @ap: list of variadic arguments
> + *
> + * Create a new row in the table. Each argument passed
> + * represents a cell in the row.
> + * Return: pointer to vshTableRowPtr row or NULL.
> + */
> +static vshTableRowPtr
> +vshTableRowNew(const char *arg, va_list ap)
> +{
> +vshTableRowPtr row = NULL;
> +char *tmp = NULL;
> +
> +if (!arg) {
> +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +_("Table row cannot be empty"));
> +goto error;
> +}
> +
> +if (VIR_ALLOC(row) < 0)
> +goto error;
> +
> +while (arg) {
> +if (VIR_STRDUP(tmp, arg) < 0)
> +goto error;
> +
> +if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0)
> +goto error;
> +
> +arg = va_arg(ap, const char *);
> +}
> +
> +return row;

[libvirt] [PATCH v4 3/3] vsh: Added tests

2018-08-22 Thread Simon Kobyda
For now, there are 9 test cases
- testVshTableNew: Creating table with empty header
- testVshTableHeader: Printing table with/without header
- testVshTableRowAppend: Appending row with various number of cells.
  Only row with same number of cells as in header is accepted.
- testUnicode: Printing table with unicode characters.
  Checking correct alignment.
- testUnicodeArabic: test opposite (right to left) writing
- testUnicodeZeroWidthChar
- testUnicodeCombiningChar
- testUnicodeNonPrintableChar,
- testNTables: Create and print varios types of tables - one column,
  one row table, table without content, standart table...

Signed-off-by: Simon Kobyda 
---
 tests/Makefile.am|   8 +
 tests/vshtabletest.c | 393 +++
 2 files changed, 401 insertions(+)
 create mode 100644 tests/vshtabletest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 21a6c823d9..136fe16f71 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ test_programs = virshtest sockettest \
virhostdevtest \
virnetdevtest \
virtypedparamtest \
+   vshtabletest \
$(NULL)
 
 test_libraries = libshunload.la \
@@ -938,6 +939,13 @@ metadatatest_SOURCES = \
testutils.c testutils.h
 metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
 
+vshtabletest_SOURCES = \
+   vshtabletest.c \
+   testutils.c testutils.h
+vshtabletest_LDADD = \
+   $(LDADDS) \
+   ../tools/libvirt_shell.la
+
 virshtest_SOURCES = \
virshtest.c \
testutils.c testutils.h
diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
new file mode 100644
index 00..48553057d4
--- /dev/null
+++ b/tests/vshtabletest.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include "testutils.h"
+#include "viralloc.h"
+#include "../tools/vsh-table.h"
+
+static int
+testVshTableNew(const void *opaque ATTRIBUTE_UNUSED)
+{
+if (vshTableNew(NULL)) {
+fprintf(stderr, "expected failure when passing null to vshTableNew\n");
+return -1;
+}
+
+return 0;
+}
+
+static int
+testVshTableHeader(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+char *act = NULL;
+const char *exp =
+" 1   fedora28   running  \n"
+" 2   rhel7.5running  \n";
+const char *exp2 =
+" Id   Name   State\n"
+"--\n"
+" 1fedora28   running  \n"
+" 2rhel7.5running  \n";
+
+vshTablePtr table = vshTableNew("Id", "Name", "State",
+NULL); //to ask about return
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+act = vshTablePrintToString(table, false);
+if (virTestCompareToString(exp, act) < 0)
+ret = -1;
+
+VIR_FREE(act);
+act = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp2, act) < 0)
+ret = -1;
+
+ cleanup:
+VIR_FREE(act);
+vshTableFree(table);
+return ret;
+}
+
+static int
+testVshTableRowAppend(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+
+vshTablePtr table = vshTableNew("Id", "Name", NULL);
+if (!table)
+goto cleanup;
+
+if (vshTableRowAppend(table, NULL) >= 0) {
+fprintf(stderr, "Appending NULL shouldn't work\n");
+ret = -1;
+}
+
+if (vshTableRowAppend(table, "2", NULL) >= 0) {
+fprintf(stderr, "Appending less items than in header\n");
+ret = -1;
+}
+
+if (vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL) >= 0) {
+fprintf(stderr, "Appending more items than in header\n");
+ret = -1;
+}
+
+if (vshTableRowAppend(table, "2", "rhel7.5", NULL) < 0) {
+fprintf(stderr, "Appending same number of items as in header&quo

[libvirt] [PATCH v4 1/3] vsh: Add API for printing tables.

2018-08-22 Thread Simon Kobyda
It solves problems with alignment of columns. Width of each column
is calculated by its biggest cell. Should solve unicode bug.
In future, it may be implemented in virsh, virt-admin...

This API has 5 public functions:
- vshTableNew - adds new table and defines its header
- vshTableRowAppend - appends new row (for same number of columns as in
header)
- vshTablePrintToStdout
- vshTablePrintToString
- vshTableFree

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Signed-off-by: Simon Kobyda 
---
 tools/Makefile.am |   4 +-
 tools/vsh-table.c | 483 ++
 tools/vsh-table.h |  42 
 3 files changed, 528 insertions(+), 1 deletion(-)
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 1452d984a0..f069167acc 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
$(READLINE_LIBS) \
../gnulib/lib/libgnu.la \
$(NULL)
-libvirt_shell_la_SOURCES = vsh.c vsh.h
+libvirt_shell_la_SOURCES = \
+   vsh.c vsh.h \
+   vsh-table.c vsh-table.h
 
 virt_host_validate_SOURCES = \
virt-host-validate.c \
diff --git a/tools/vsh-table.c b/tools/vsh-table.c
new file mode 100644
index 00..6e1793e4e3
--- /dev/null
+++ b/tools/vsh-table.c
@@ -0,0 +1,483 @@
+/*
+ * vsh-table.c: table printing helper
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Simon Kobyda 
+ *
+ */
+
+#include 
+#include "vsh-table.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "c-ctype.h"
+
+#include "viralloc.h"
+#include "virbuffer.h"
+#include "virstring.h"
+#include "virsh-util.h"
+
+#define HEX_ENCODE_LENGTH 4 /* represents length of '\xNN' */
+
+struct _vshTableRow {
+char **cells;
+size_t ncells;
+};
+
+struct _vshTable {
+vshTableRowPtr *rows;
+size_t nrows;
+};
+
+static void
+vshTableRowFree(vshTableRowPtr row)
+{
+size_t i;
+
+if (!row)
+return;
+
+for (i = 0; i < row->ncells; i++)
+VIR_FREE(row->cells[i]);
+
+VIR_FREE(row->cells);
+VIR_FREE(row);
+}
+
+void
+vshTableFree(vshTablePtr table)
+{
+size_t i;
+
+if (!table)
+return;
+
+for (i = 0; i < table->nrows; i++)
+vshTableRowFree(table->rows[i]);
+VIR_FREE(table->rows);
+VIR_FREE(table);
+}
+
+/**
+ * vshTableRowNew:
+ * @arg: the first argument.
+ * @ap: list of variadic arguments
+ *
+ * Create a new row in the table. Each argument passed
+ * represents a cell in the row.
+ * Return: pointer to vshTableRowPtr row or NULL.
+ */
+static vshTableRowPtr
+vshTableRowNew(const char *arg, va_list ap)
+{
+vshTableRowPtr row = NULL;
+char *tmp = NULL;
+
+if (!arg) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Table row cannot be empty"));
+goto error;
+}
+
+if (VIR_ALLOC(row) < 0)
+goto error;
+
+while (arg) {
+if (VIR_STRDUP(tmp, arg) < 0)
+goto error;
+
+if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0)
+goto error;
+
+arg = va_arg(ap, const char *);
+}
+
+return row;
+
+ error:
+vshTableRowFree(row);
+return NULL;
+}
+
+/**
+ * vshTableNew:
+ * @arg: List of column names (NULL terminated)
+ *
+ * Create a new table.
+ *
+ * Returns: pointer to table or NULL.
+ */
+vshTablePtr
+vshTableNew(const char *arg, ...)
+{
+vshTablePtr table;
+vshTableRowPtr header = NULL;
+va_list ap;
+
+if (VIR_ALLOC(table) < 0)
+goto error;
+
+va_start(ap, arg);
+header = vshTableRowNew(arg, ap);
+va_end(ap);
+
+if (!header)
+goto error;
+
+if (VIR_APPEND_ELEMENT(table->rows, table->nrows, header) < 0)
+goto error;
+
+return table;
+ error:
+vshTableRowFree(header);
+vshTableFree(table);
+return NULL;
+}
+
+/**
+ * vshTableRowAppend:
+ * @table: table to append to
+ * @arg: cells of the row (NULL terminated)
+ *
+ * Append new row into the @

[libvirt] [PATCH v4 2/3] virsh: Implement new table API for virsh list

2018-08-22 Thread Simon Kobyda
Instead of printing it straight in virsh, it creates table struct
which is filled with header and rows(domains). It allows us to know
more about table before printing to calculate alignment right.

Signed-off-by: Simon Kobyda 
---
 tests/virshtest.c| 14 ++--
 tools/virsh-domain-monitor.c | 43 
 2 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/tests/virshtest.c b/tests/virshtest.c
index 94548a82d1..10cd0d356b 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -98,9 +98,9 @@ static int testCompareListDefault(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_DEFAULT, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 test   running\n\
+ Id   Name   State\n\
+--\n\
+ 1test   running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
@@ -109,10 +109,10 @@ static int testCompareListCustom(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_CUSTOM, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 fv0running\n\
- 2 fc4running\n\
+ Id   Name   State\n\
+--\n\
+ 1fv0running  \n\
+ 2fc4running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b4f9739b..adc5bb1a7a 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -39,6 +39,7 @@
 #include "virmacaddr.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 VIR_ENUM_DECL(virshDomainIOError)
 VIR_ENUM_IMPL(virshDomainIOError,
@@ -1901,6 +1902,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
 unsigned int id;
 unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+vshTablePtr table = NULL;
 
 /* construct filter flags */
 if (vshCommandOptBool(cmd, "inactive") ||
@@ -1940,15 +1942,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 /* print table header in legacy mode */
 if (optTable) {
 if (optTitle)
-vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
-  _("Id"), _("Name"), _("State"), _("Title"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Name", "State", "Title", NULL);
 else
-vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
-  _("Id"), _("Name"), _("State"),
-  "-"
-  "---");
+table = vshTableNew("Id", "Name", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->ndomains; i++) {
@@ -1973,20 +1972,22 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 if (optTitle) {
 if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
 goto cleanup;
-
-vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state),
- title);
-
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  title, NULL) < 0)
+goto cleanup;
 VIR_FREE(title);
 } else {
-vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state));
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  NULL) < 0)
+goto cleanup;
 }
+
 } el

[libvirt] [PATCH v4 0/3] vsh: Introduce new API for printing tables

2018-08-22 Thread Simon Kobyda
Created new API for priting tables, mainly to solve alignment problems.
Implemented these test to virsh list. In the future, API may be
everywhere in virsh and virt-admin.
Also wrote basic tests for the new API, and corrected tests in virshtest
which are influenced by implementation of the API in virsh list.

Changes in v4:
- fixed width calculation for zero-width, nonprintable and combined
character. (pulled some code from linux-util)
- added tests for cases mentioned above
- changed usage of vshControl variables. From now on PrintToStdout calls
PrintToString and then prints returned string to stdout

Changes in v3:
- changed encoding of 3/3 patch, otherwise it cannot be applied

Changes in v2:
- added tests
- fixed alignment for unicode character which span more spaces
- moved ncolumns check to vshTableRowAppend
- changed arguments for functions vshTablePrint, vshTablePrintToStdout,
vshTablePrintToString

Simon Kobyda (3):
  vsh: Add API for printing tables.
  virsh: Implement new table API for virsh list
  vsh: Added tests

 tests/Makefile.am|   8 +
 tests/virshtest.c|  14 +-
 tests/vshtabletest.c | 393 
 tools/Makefile.am|   4 +-
 tools/virsh-domain-monitor.c |  43 ++--
 tools/vsh-table.c| 483 +++
 tools/vsh-table.h|  42 +++
 7 files changed, 960 insertions(+), 27 deletions(-)
 create mode 100644 tests/vshtabletest.c
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 1/3] vsh: Add API for printing tables.

2018-08-22 Thread Simon Kobyda
On Tue, 2018-08-21 at 11:46 +0100, Daniel P. Berrangé wrote:
> On Tue, Aug 21, 2018 at 12:27:34PM +0200, Michal Privoznik wrote:
> > On 08/21/2018 11:18 AM, Simon Kobyda wrote:
> > > On Thu, 2018-08-16 at 12:28 +0100, Daniel P. Berrangé wrote:
> > > > On Thu, Aug 16, 2018 at 12:56:24PM +0200, Simon Kobyda wrote:
> > > > > 
> > > > 
> > > > After asking around I have found the right solution that we
> > > > need to
> > > > use
> > > > for measuring string width.  mbstowcs()/wcswidth() will get the
> > > > answer
> > > > wrong wrt zero-width characters, combining characters, non-
> > > > printable
> > > > characters, etc. We need to use the libunistring library:
> > > > 
> > > >   
> > > > 
https://www.gnu.org/software/libunistring/manual/libunistring.html#uniwidth_002eh
> > > > 
> > > > 
> > > 
> > > I've tried what you've suggested, but it seems that it doesn't
> > > work
> > > well with all unicode characters. I'm looking into the code of
> > > the
> > > library, and each function uN_strwidth calls function uN_width,
> > > and
> > > that function calls uc_width for calculation of width of
> > > characters.
> > > And if we look into the code of uc_width here:
> > > 
> > > 
http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/uniwidth/width.c;h=269cfc77f50a3b9802e5fb5620ff8bcf95e05e40;hb=HEAD#l415
> > > it seems that this library is limited only to certain unicodes,
> > > e.g.:
> > > hangul characters, angle brackets, CJK characters... But it
> > > doesn't
> > > cover all multiple-width characters. Example: I try to throw any
> > > emoji
> > > (e.g. , 呂, ), it returns width of 1 column for each charact
> > > er, nevertheless these characters have width of 2 columns on
> > > terminal.
> > > 
> > > BTW, it seems unistring library imports those funcions from
> > > gnulib.
> > 
> > I guess the only option then is to try smartcols [1]. If it is good
> > for
> > util-linux it's going to be good for us too. Although, I'd prefer
> > to
> > have our own wrappers over their API.
> > 
> > https://github.com/karelzak/util-linux/tree/master/libsmartcols
> 
> The util-linux code does something that uses mbstowcs / wcwidth to
> convert the characters and count their width, sort of like the
> original
> version of this patch. They have further code that decides to convert
> certain unicode characters into "\xNN" escaped sequences, which
> avoids
> the problems I raised wrt non-printable strings.
> 
>https://github.com/karelzak/util-linux/blob/master/lib/mbsalign.c
> 
> So we could pull that helper API into our code, since its LGPL
> loicensed.
> I'm unclear if this correctly handles all the cases or not though as
> there's no unit tests for it in util-linux AFACT.
> 
> Really the only way for us to be sure is to provide a unit test which
> stresses our the code with a variety of unicode input strings.

About unit tests. Right now i've got tests for non-pritnable, zero-
width, combining characters and opposite (rigth to left) writing.
Anybody got any idea what else could be problematic with
mbstowcs()/wcswidth(), and therefore tested?

Simon Kobyda.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 1/3] vsh: Add API for printing tables.

2018-08-21 Thread Simon Kobyda
On Thu, 2018-08-16 at 12:28 +0100, Daniel P. Berrangé wrote:
> On Thu, Aug 16, 2018 at 12:56:24PM +0200, Simon Kobyda wrote:
> > 
> 
> After asking around I have found the right solution that we need to
> use
> for measuring string width.  mbstowcs()/wcswidth() will get the
> answer
> wrong wrt zero-width characters, combining characters, non-printable
> characters, etc. We need to use the libunistring library:
> 
>   
> https://www.gnu.org/software/libunistring/manual/libunistring.html#uniwidth_002eh
> 
> 
I've tried what you've suggested, but it seems that it doesn't work
well with all unicode characters. I'm looking into the code of the
library, and each function uN_strwidth calls function uN_width, and
that function calls uc_width for calculation of width of characters.
And if we look into the code of uc_width here:

http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/uniwidth/width.c;h=269cfc77f50a3b9802e5fb5620ff8bcf95e05e40;hb=HEAD#l415
it seems that this library is limited only to certain unicodes, e.g.:
hangul characters, angle brackets, CJK characters... But it doesn't
cover all multiple-width characters. Example: I try to throw any emoji
(e.g. , 呂, ), it returns width of 1 column for each charact
er, nevertheless these characters have width of 2 columns on terminal.

BTW, it seems unistring library imports those funcions from gnulib.

Simon Kobyda.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v3 2/3] virsh: Implement new table API for virsh list

2018-08-16 Thread Simon Kobyda
Instead of printing it straight in virsh, it creates table struct
which is filled with header and rows(domains). It allows us to know
more about table before printing to calculate alignment right.

Signed-off-by: Simon Kobyda 
---
 tests/virshtest.c| 14 ++--
 tools/virsh-domain-monitor.c | 43 
 2 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/tests/virshtest.c b/tests/virshtest.c
index 94548a82d1..10cd0d356b 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -98,9 +98,9 @@ static int testCompareListDefault(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_DEFAULT, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 test   running\n\
+ Id   Name   State\n\
+--\n\
+ 1test   running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
@@ -109,10 +109,10 @@ static int testCompareListCustom(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_CUSTOM, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 fv0running\n\
- 2 fc4running\n\
+ Id   Name   State\n\
+--\n\
+ 1fv0running  \n\
+ 2fc4running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b4f9739b..adc5bb1a7a 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -39,6 +39,7 @@
 #include "virmacaddr.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 VIR_ENUM_DECL(virshDomainIOError)
 VIR_ENUM_IMPL(virshDomainIOError,
@@ -1901,6 +1902,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
 unsigned int id;
 unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+vshTablePtr table = NULL;
 
 /* construct filter flags */
 if (vshCommandOptBool(cmd, "inactive") ||
@@ -1940,15 +1942,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 /* print table header in legacy mode */
 if (optTable) {
 if (optTitle)
-vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
-  _("Id"), _("Name"), _("State"), _("Title"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Name", "State", "Title", NULL);
 else
-vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
-  _("Id"), _("Name"), _("State"),
-  "-"
-  "---");
+table = vshTableNew("Id", "Name", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->ndomains; i++) {
@@ -1973,20 +1972,22 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 if (optTitle) {
 if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
 goto cleanup;
-
-vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state),
- title);
-
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  title, NULL) < 0)
+goto cleanup;
 VIR_FREE(title);
 } else {
-vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state));
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  NULL) < 0)
+goto cleanup;
 }
+
 } el

[libvirt] [PATCH v3 0/3] vsh: Introduce new API for printing tables

2018-08-16 Thread Simon Kobyda
Created new API for priting tables, mainly to solve alignment problems.
Implemented these test to virsh list. In the future, API may be
everywhere in virsh and virt-admin.
Also wrote basic tests for the new API, and corrected tests in virshtest
which are influenced by implementation of the API in virsh list.

Changes in v3:
- changed encoding of 3/3 patch, otherwise it cannot be applied

Changes in v2:
- added tests
- fixed alignment for unicode character which span more spaces
- moved ncolumns check to vshTableRowAppend
- changed arguments for functions vshTablePrint, vshTablePrintToStdout,
vshTablePrintToString

Simon Kobyda (3):
  vsh: Add API for printing tables.
  virsh: Implement new table API for virsh list
  vsh: Added tests

 tests/Makefile.am|   8 +
 tests/virshtest.c|  14 +-
 tests/vshtabletest.c | 247 +
 tools/Makefile.am|   4 +-
 tools/virsh-domain-monitor.c |  43 ++--
 tools/vsh-table.c| 413 +++
 tools/vsh-table.h|  42 
 7 files changed, 744 insertions(+), 27 deletions(-)
 create mode 100644 tests/vshtabletest.c
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v3 1/3] vsh: Add API for printing tables.

2018-08-16 Thread Simon Kobyda
It solves problems with alignment of columns. Width of each column
is calculated by its biggest cell. Should solve unicode bug.
In future, it may be implemented in virsh, virt-admin...

This API has 5 public functions:
- vshTableNew - adds new table and defines its header
- vshTableRowAppend - appends new row (for same number of columns as in
header)
- vshTablePrintToStdout
- vshTablePrintToString
- vshTableFree

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Signed-off-by: Simon Kobyda 
---
 tools/Makefile.am |   4 +-
 tools/vsh-table.c | 413 ++
 tools/vsh-table.h |  42 +
 3 files changed, 458 insertions(+), 1 deletion(-)
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 1452d984a0..f069167acc 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
$(READLINE_LIBS) \
../gnulib/lib/libgnu.la \
$(NULL)
-libvirt_shell_la_SOURCES = vsh.c vsh.h
+libvirt_shell_la_SOURCES = \
+   vsh.c vsh.h \
+   vsh-table.c vsh-table.h
 
 virt_host_validate_SOURCES = \
virt-host-validate.c \
diff --git a/tools/vsh-table.c b/tools/vsh-table.c
new file mode 100644
index 00..8842e4e4fd
--- /dev/null
+++ b/tools/vsh-table.c
@@ -0,0 +1,413 @@
+/*
+ * vsh-table.c: table printing helper
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Simon Kobyda 
+ *
+ */
+
+#include 
+#include "vsh-table.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "viralloc.h"
+#include "virbuffer.h"
+#include "virstring.h"
+#include "virsh-util.h"
+
+typedef void (*vshPrintCB)(vshControl *ctl, const char *fmt, ...);
+
+struct _vshTableRow {
+char **cells;
+size_t ncells;
+};
+
+struct _vshTable {
+vshTableRowPtr *rows;
+size_t nrows;
+};
+
+static void
+vshTableRowFree(vshTableRowPtr row)
+{
+size_t i;
+
+if (!row)
+return;
+
+for (i = 0; i < row->ncells; i++)
+VIR_FREE(row->cells[i]);
+
+VIR_FREE(row->cells);
+VIR_FREE(row);
+}
+
+void
+vshTableFree(vshTablePtr table)
+{
+size_t i;
+
+if (!table)
+return;
+
+for (i = 0; i < table->nrows; i++)
+vshTableRowFree(table->rows[i]);
+VIR_FREE(table->rows);
+VIR_FREE(table);
+}
+
+/**
+ * vshTableRowNew:
+ * @arg: the first argument.
+ * @ap: list of variadic arguments
+ *
+ * Create a new row in the table. Each argument passed
+ * represents a cell in the row.
+ * Return: pointer to vshTableRowPtr row or NULL.
+ */
+static vshTableRowPtr
+vshTableRowNew(const char *arg, va_list ap)
+{
+vshTableRowPtr row = NULL;
+char *tmp = NULL;
+
+if (!arg) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Table row cannot be empty"));
+goto error;
+}
+
+if (VIR_ALLOC(row) < 0)
+goto error;
+
+while (arg) {
+if (VIR_STRDUP(tmp, arg) < 0)
+goto error;
+
+if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0)
+goto error;
+
+arg = va_arg(ap, const char *);
+}
+
+return row;
+
+ error:
+vshTableRowFree(row);
+return NULL;
+}
+
+/**
+ * vshTableNew:
+ * @arg: List of column names (NULL terminated)
+ *
+ * Create a new table.
+ *
+ * Returns: pointer to table or NULL.
+ */
+vshTablePtr
+vshTableNew(const char *arg, ...)
+{
+vshTablePtr table;
+vshTableRowPtr header = NULL;
+va_list ap;
+
+if (VIR_ALLOC(table) < 0)
+goto error;
+
+va_start(ap, arg);
+header = vshTableRowNew(arg, ap);
+va_end(ap);
+
+if (!header)
+goto error;
+
+if (VIR_APPEND_ELEMENT(table->rows, table->nrows, header) < 0)
+goto error;
+
+return table;
+ error:
+vshTableRowFree(header);
+vshTableFree(table);
+return NULL;
+}
+
+/**
+ * vshTableRowAppend:
+ * @table: table to append to
+ * @arg: cells of the row (NULL terminated)
+ *
+ * Append new row into the @table. The number of cells in t

[libvirt] [PATCH v3 3/3] vsh: Added tests

2018-08-16 Thread Simon Kobyda
For now, there are 5 test cases
- testVshTableNew: Creating table with empty header
- testVshTableHeader: Printing table with/without header
- testVshTableRowAppend: Appending row with various number of cells.
  Only row with same number of cells as in header is accepted.
- testVshTableNewUnicode: Printing table with unicode characters.
  Checking correct alignment.
- testNTables: Create and print various types of tables - one column,
  one row table, table without content, standard table...

Signed-off-by: Simon Kobyda 
---
 tests/Makefile.am|   8 ++
 tests/vshtabletest.c | 247 +++
 2 files changed, 255 insertions(+)
 create mode 100644 tests/vshtabletest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 21a6c823d9..136fe16f71 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ test_programs = virshtest sockettest \
virhostdevtest \
virnetdevtest \
virtypedparamtest \
+   vshtabletest \
$(NULL)
 
 test_libraries = libshunload.la \
@@ -938,6 +939,13 @@ metadatatest_SOURCES = \
testutils.c testutils.h
 metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
 
+vshtabletest_SOURCES = \
+   vshtabletest.c \
+   testutils.c testutils.h
+vshtabletest_LDADD = \
+   $(LDADDS) \
+   ../tools/libvirt_shell.la
+
 virshtest_SOURCES = \
virshtest.c \
testutils.c testutils.h
diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
new file mode 100644
index 00..b41a205761
--- /dev/null
+++ b/tests/vshtabletest.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include "testutils.h"
+#include "viralloc.h"
+#include "../tools/vsh-table.h"
+
+static int
+testVshTableNew(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+
+if (vshTableNew(NULL)) {
+fprintf(stderr, "expected failure when passing null to"
+"vshtablenew\n");
+ret = -1;
+}
+
+return ret;
+}
+
+static int
+testVshTableHeader(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+char *out;
+const char *exp = "\
+ 1   fedora28   running  \n\
+ 2   rhel7.5running  \n";
+const char *exp2 = "\
+ Id   Name   State\n\
+--\n\
+ 1fedora28   running  \n\
+ 2rhel7.5running  \n";
+
+vshTablePtr table = vshTableNew("Id", "Name", "State",
+NULL); //to ask about return
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+out = vshTablePrintToString(table, false);
+if (virTestCompareToString(exp, out) < 0)
+ret = -1;
+
+VIR_FREE(out);
+out = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp2, out) < 0)
+ret = -1;
+
+ cleanup:
+VIR_FREE(out);
+vshTableFree(table);
+return ret;
+}
+
+static int
+testVshTableNewUnicode(const void *opaque ATTRIBUTE_UNUSED)
+{
+
+int ret = 0;
+char *out;
+
+char *locale = setlocale(LC_CTYPE, NULL);
+if (!setlocale(LC_CTYPE, "en_US.UTF-8"))
+return EXIT_AM_SKIP;
+
+const char *exp = "\
+ Id   名稱  государство  \n\
+-\n\
+ 1fedora28  running  \n\
+ 2rhel7.5   running  \n";
+vshTablePtr table;
+
+table = vshTableNew("Id", "名稱", "государство", NULL);
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+out = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp, out) < 0)
+ret = -1;
+
+ cleanup:
+setlocale(LC_CTYPE, locale);
+VIR_FREE(out);
+vshTableFree(table);
+

Re: [libvirt] [PATCH v2 0/6] fdaskljrew

2018-08-16 Thread Simon Kobyda
I send this by mistake. Sorry.

Simon

On Thu, 2018-08-16 at 10:48 +0100, Daniel P. Berrangé wrote:
> On Thu, Aug 16, 2018 at 11:11:26AM +0200, Simon Kobyda wrote:
> > rpdwrewrewr
> 
> Please use a sensible subject line, and provide useful information
> about
> the patch series in this cover letter.
> 
> > 
> > Simon Kobyda (6):
> >   vsh: Add API for printing tables.
> >   virsh: Implement new table API for virsh list
> >   vsh: Added tests
> >   virsh: Implement vsh-table to iface-list
> >   virsh: Implement vshTable API to net-list and net-dhcp-leases
> >   virsh: Implement vshTable API to secret-list
> > 
> >  tests/Makefile.am|   8 +
> >  tests/virshtest.c|  14 +-
> >  tests/vshtabletest.c | 247 +
> >  tools/Makefile.am|   4 +-
> >  tools/virsh-domain-monitor.c |  43 ++--
> >  tools/virsh-interface.c  |  27 ++-
> >  tools/virsh-network.c|  50 +++--
> >  tools/virsh-secret.c |  30 ++-
> >  tools/vsh-table.c| 413
> > +++
> >  tools/vsh-table.h|  42 
> >  10 files changed, 817 insertions(+), 61 deletions(-)
> >  create mode 100644 tests/vshtabletest.c
> >  create mode 100644 tools/vsh-table.c
> >  create mode 100644 tools/vsh-table.h
> > 
> > -- 
> > 2.17.1
> > 
> > --
> > libvir-list mailing list
> > libvir-list@redhat.com
> > https://www.redhat.com/mailman/listinfo/libvir-list
> 
> Regards,
> Daniel

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2 3/6] vsh: Added tests

2018-08-16 Thread Simon Kobyda
For now, there are 5 test cases
- testVshTableNew: Creating table with empty header
- testVshTableHeader: Printing table with/without header
- testVshTableRowAppend: Appending row with various number of cells.
  Only row with same number of cells as in header is accepted.
- testVshTableNewUnicode: Printing table with unicode characters.
  Checking correct alignment.
- testNTables: Create and print varios types of tables - one column,
  one row table, table without content, standart table...

Signed-off-by: Simon Kobyda 
---
 tests/Makefile.am|   8 ++
 tests/vshtabletest.c | 247 +++
 2 files changed, 255 insertions(+)
 create mode 100644 tests/vshtabletest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 302b50e1cd..89c2965d86 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ test_programs = virshtest sockettest \
virhostdevtest \
virnetdevtest \
virtypedparamtest \
+   vshtabletest \
$(NULL)
 
 test_libraries = libshunload.la \
@@ -938,6 +939,13 @@ metadatatest_SOURCES = \
testutils.c testutils.h
 metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
 
+vshtabletest_SOURCES = \
+   vshtabletest.c \
+   testutils.c testutils.h
+vshtabletest_LDADD = \
+   $(LDADDS) \
+   ../tools/libvirt_shell.la
+
 virshtest_SOURCES = \
virshtest.c \
testutils.c testutils.h
diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
new file mode 100644
index 00..b41a205761
--- /dev/null
+++ b/tests/vshtabletest.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include "testutils.h"
+#include "viralloc.h"
+#include "../tools/vsh-table.h"
+
+static int
+testVshTableNew(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+
+if (vshTableNew(NULL)) {
+fprintf(stderr, "expected failure when passing null to"
+"vshtablenew\n");
+ret = -1;
+}
+
+return ret;
+}
+
+static int
+testVshTableHeader(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+char *out;
+const char *exp = "\
+ 1   fedora28   running  \n\
+ 2   rhel7.5running  \n";
+const char *exp2 = "\
+ Id   Name   State\n\
+--\n\
+ 1fedora28   running  \n\
+ 2rhel7.5running  \n";
+
+vshTablePtr table = vshTableNew("Id", "Name", "State",
+NULL); //to ask about return
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+out = vshTablePrintToString(table, false);
+if (virTestCompareToString(exp, out) < 0)
+ret = -1;
+
+VIR_FREE(out);
+out = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp2, out) < 0)
+ret = -1;
+
+ cleanup:
+VIR_FREE(out);
+vshTableFree(table);
+return ret;
+}
+
+static int
+testVshTableNewUnicode(const void *opaque ATTRIBUTE_UNUSED)
+{
+
+int ret = 0;
+char *out;
+
+char *locale = setlocale(LC_CTYPE, NULL);
+if (!setlocale(LC_CTYPE, "en_US.UTF-8"))
+return EXIT_AM_SKIP;
+
+const char *exp = "\
+ Id   名稱  государство  \n\
+-\n\
+ 1fedora28  running  \n\
+ 2rhel7.5   running  \n";
+vshTablePtr table;
+
+table = vshTableNew("Id", "名稱", "государство", NULL);
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+out = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp, out) < 0)
+ret = -1;
+
+ cleanup:
+setlocale(LC_CTYPE, locale);
+VIR_FREE(out);
+vshTableFree(table);
+retur

[libvirt] [PATCH v2 2/6] virsh: Implement new table API for virsh list

2018-08-16 Thread Simon Kobyda
Instead of printing it straight in virsh, it creates table struct
which is filled with header and rows(domains). It allows us to know
more about table before printing to calculate alignment right.

Signed-off-by: Simon Kobyda 
---
 tests/virshtest.c| 14 ++--
 tools/virsh-domain-monitor.c | 43 
 2 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/tests/virshtest.c b/tests/virshtest.c
index 94548a82d1..10cd0d356b 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -98,9 +98,9 @@ static int testCompareListDefault(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_DEFAULT, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 test   running\n\
+ Id   Name   State\n\
+--\n\
+ 1test   running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
@@ -109,10 +109,10 @@ static int testCompareListCustom(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_CUSTOM, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 fv0running\n\
- 2 fc4running\n\
+ Id   Name   State\n\
+--\n\
+ 1fv0running  \n\
+ 2fc4running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b4f9739b..adc5bb1a7a 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -39,6 +39,7 @@
 #include "virmacaddr.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 VIR_ENUM_DECL(virshDomainIOError)
 VIR_ENUM_IMPL(virshDomainIOError,
@@ -1901,6 +1902,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
 unsigned int id;
 unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+vshTablePtr table = NULL;
 
 /* construct filter flags */
 if (vshCommandOptBool(cmd, "inactive") ||
@@ -1940,15 +1942,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 /* print table header in legacy mode */
 if (optTable) {
 if (optTitle)
-vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
-  _("Id"), _("Name"), _("State"), _("Title"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Name", "State", "Title", NULL);
 else
-vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
-  _("Id"), _("Name"), _("State"),
-  "-"
-  "---");
+table = vshTableNew("Id", "Name", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->ndomains; i++) {
@@ -1973,20 +1972,22 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 if (optTitle) {
 if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
 goto cleanup;
-
-vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state),
- title);
-
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  title, NULL) < 0)
+goto cleanup;
 VIR_FREE(title);
 } else {
-vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state));
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  NULL) < 0)
+goto cleanup;
 }
+
 } el

[libvirt] [PATCH v2 0/6] fdaskljrew

2018-08-16 Thread Simon Kobyda
rpdwrewrewr

Simon Kobyda (6):
  vsh: Add API for printing tables.
  virsh: Implement new table API for virsh list
  vsh: Added tests
  virsh: Implement vsh-table to iface-list
  virsh: Implement vshTable API to net-list and net-dhcp-leases
  virsh: Implement vshTable API to secret-list

 tests/Makefile.am|   8 +
 tests/virshtest.c|  14 +-
 tests/vshtabletest.c | 247 +
 tools/Makefile.am|   4 +-
 tools/virsh-domain-monitor.c |  43 ++--
 tools/virsh-interface.c  |  27 ++-
 tools/virsh-network.c|  50 +++--
 tools/virsh-secret.c |  30 ++-
 tools/vsh-table.c| 413 +++
 tools/vsh-table.h|  42 
 10 files changed, 817 insertions(+), 61 deletions(-)
 create mode 100644 tests/vshtabletest.c
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 1/6] vsh: Add API for printing tables.

2018-08-16 Thread Simon Kobyda
It solves problems with alignment of columns. Width of each column
is calculated by its biggest cell. Should solve unicode bug.
In future, it may be implemented in virsh, virt-admin...

This API has 5 public functions:
- vshTableNew - adds new table and defines its header
- vshTableRowAppend - appends new row (for same number of columns as in
header)
- vshTablePrintToStdout
- vshTablePrintToString
- vshTableFree

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Signed-off-by: Simon Kobyda 
---
 tools/Makefile.am |   4 +-
 tools/vsh-table.c | 413 ++
 tools/vsh-table.h |  42 +
 3 files changed, 458 insertions(+), 1 deletion(-)
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 26c887649e..ed23575aa7 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
$(READLINE_LIBS) \
../gnulib/lib/libgnu.la \
$(NULL)
-libvirt_shell_la_SOURCES = vsh.c vsh.h
+libvirt_shell_la_SOURCES = \
+   vsh.c vsh.h \
+   vsh-table.c vsh-table.h
 
 virt_host_validate_SOURCES = \
virt-host-validate.c \
diff --git a/tools/vsh-table.c b/tools/vsh-table.c
new file mode 100644
index 00..8842e4e4fd
--- /dev/null
+++ b/tools/vsh-table.c
@@ -0,0 +1,413 @@
+/*
+ * vsh-table.c: table printing helper
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Simon Kobyda 
+ *
+ */
+
+#include 
+#include "vsh-table.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "viralloc.h"
+#include "virbuffer.h"
+#include "virstring.h"
+#include "virsh-util.h"
+
+typedef void (*vshPrintCB)(vshControl *ctl, const char *fmt, ...);
+
+struct _vshTableRow {
+char **cells;
+size_t ncells;
+};
+
+struct _vshTable {
+vshTableRowPtr *rows;
+size_t nrows;
+};
+
+static void
+vshTableRowFree(vshTableRowPtr row)
+{
+size_t i;
+
+if (!row)
+return;
+
+for (i = 0; i < row->ncells; i++)
+VIR_FREE(row->cells[i]);
+
+VIR_FREE(row->cells);
+VIR_FREE(row);
+}
+
+void
+vshTableFree(vshTablePtr table)
+{
+size_t i;
+
+if (!table)
+return;
+
+for (i = 0; i < table->nrows; i++)
+vshTableRowFree(table->rows[i]);
+VIR_FREE(table->rows);
+VIR_FREE(table);
+}
+
+/**
+ * vshTableRowNew:
+ * @arg: the first argument.
+ * @ap: list of variadic arguments
+ *
+ * Create a new row in the table. Each argument passed
+ * represents a cell in the row.
+ * Return: pointer to vshTableRowPtr row or NULL.
+ */
+static vshTableRowPtr
+vshTableRowNew(const char *arg, va_list ap)
+{
+vshTableRowPtr row = NULL;
+char *tmp = NULL;
+
+if (!arg) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Table row cannot be empty"));
+goto error;
+}
+
+if (VIR_ALLOC(row) < 0)
+goto error;
+
+while (arg) {
+if (VIR_STRDUP(tmp, arg) < 0)
+goto error;
+
+if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0)
+goto error;
+
+arg = va_arg(ap, const char *);
+}
+
+return row;
+
+ error:
+vshTableRowFree(row);
+return NULL;
+}
+
+/**
+ * vshTableNew:
+ * @arg: List of column names (NULL terminated)
+ *
+ * Create a new table.
+ *
+ * Returns: pointer to table or NULL.
+ */
+vshTablePtr
+vshTableNew(const char *arg, ...)
+{
+vshTablePtr table;
+vshTableRowPtr header = NULL;
+va_list ap;
+
+if (VIR_ALLOC(table) < 0)
+goto error;
+
+va_start(ap, arg);
+header = vshTableRowNew(arg, ap);
+va_end(ap);
+
+if (!header)
+goto error;
+
+if (VIR_APPEND_ELEMENT(table->rows, table->nrows, header) < 0)
+goto error;
+
+return table;
+ error:
+vshTableRowFree(header);
+vshTableFree(table);
+return NULL;
+}
+
+/**
+ * vshTableRowAppend:
+ * @table: table to append to
+ * @arg: cells of the row (NULL terminated)
+ *
+ * Append new row into the @table. The number of cells in t

[libvirt] [PATCH v2 1/3] vsh: Add API for printing tables.

2018-08-15 Thread Simon Kobyda
It solves problems with alignment of columns. Width of each column
is calculated by its biggest cell. Should solve unicode bug.
In future, it may be implemented in virsh, virt-admin...

This API has 5 public functions:
- vshTableNew - adds new table and defines its header
- vshTableRowAppend - appends new row (for same number of columns as in
header)
- vshTablePrintToStdout
- vshTablePrintToString
- vshTableFree

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Signed-off-by: Simon Kobyda 
---
 tools/Makefile.am |   4 +-
 tools/vsh-table.c | 413 ++
 tools/vsh-table.h |  42 +
 3 files changed, 458 insertions(+), 1 deletion(-)
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 26c887649e..ed23575aa7 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
$(READLINE_LIBS) \
../gnulib/lib/libgnu.la \
$(NULL)
-libvirt_shell_la_SOURCES = vsh.c vsh.h
+libvirt_shell_la_SOURCES = \
+   vsh.c vsh.h \
+   vsh-table.c vsh-table.h
 
 virt_host_validate_SOURCES = \
virt-host-validate.c \
diff --git a/tools/vsh-table.c b/tools/vsh-table.c
new file mode 100644
index 00..8842e4e4fd
--- /dev/null
+++ b/tools/vsh-table.c
@@ -0,0 +1,413 @@
+/*
+ * vsh-table.c: table printing helper
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Simon Kobyda 
+ *
+ */
+
+#include 
+#include "vsh-table.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "viralloc.h"
+#include "virbuffer.h"
+#include "virstring.h"
+#include "virsh-util.h"
+
+typedef void (*vshPrintCB)(vshControl *ctl, const char *fmt, ...);
+
+struct _vshTableRow {
+char **cells;
+size_t ncells;
+};
+
+struct _vshTable {
+vshTableRowPtr *rows;
+size_t nrows;
+};
+
+static void
+vshTableRowFree(vshTableRowPtr row)
+{
+size_t i;
+
+if (!row)
+return;
+
+for (i = 0; i < row->ncells; i++)
+VIR_FREE(row->cells[i]);
+
+VIR_FREE(row->cells);
+VIR_FREE(row);
+}
+
+void
+vshTableFree(vshTablePtr table)
+{
+size_t i;
+
+if (!table)
+return;
+
+for (i = 0; i < table->nrows; i++)
+vshTableRowFree(table->rows[i]);
+VIR_FREE(table->rows);
+VIR_FREE(table);
+}
+
+/**
+ * vshTableRowNew:
+ * @arg: the first argument.
+ * @ap: list of variadic arguments
+ *
+ * Create a new row in the table. Each argument passed
+ * represents a cell in the row.
+ * Return: pointer to vshTableRowPtr row or NULL.
+ */
+static vshTableRowPtr
+vshTableRowNew(const char *arg, va_list ap)
+{
+vshTableRowPtr row = NULL;
+char *tmp = NULL;
+
+if (!arg) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Table row cannot be empty"));
+goto error;
+}
+
+if (VIR_ALLOC(row) < 0)
+goto error;
+
+while (arg) {
+if (VIR_STRDUP(tmp, arg) < 0)
+goto error;
+
+if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0)
+goto error;
+
+arg = va_arg(ap, const char *);
+}
+
+return row;
+
+ error:
+vshTableRowFree(row);
+return NULL;
+}
+
+/**
+ * vshTableNew:
+ * @arg: List of column names (NULL terminated)
+ *
+ * Create a new table.
+ *
+ * Returns: pointer to table or NULL.
+ */
+vshTablePtr
+vshTableNew(const char *arg, ...)
+{
+vshTablePtr table;
+vshTableRowPtr header = NULL;
+va_list ap;
+
+if (VIR_ALLOC(table) < 0)
+goto error;
+
+va_start(ap, arg);
+header = vshTableRowNew(arg, ap);
+va_end(ap);
+
+if (!header)
+goto error;
+
+if (VIR_APPEND_ELEMENT(table->rows, table->nrows, header) < 0)
+goto error;
+
+return table;
+ error:
+vshTableRowFree(header);
+vshTableFree(table);
+return NULL;
+}
+
+/**
+ * vshTableRowAppend:
+ * @table: table to append to
+ * @arg: cells of the row (NULL terminated)
+ *
+ * Append new row into the @table. The number of cells in t

[libvirt] [PATCH v2 3/3] vsh: Added tests

2018-08-15 Thread Simon Kobyda
For now, there are 5 test cases
- testVshTableNew: Creating table with empty header
- testVshTableHeader: Printing table with/without header
- testVshTableRowAppend: Appending row with various number of cells.
  Only row with same number of cells as in header is accepted.
- testVshTableNewUnicode: Printing table with unicode characters.
  Checking correct alignment.
- testNTables: Create and print varios types of tables - one column,
  one row table, table without content, standart table...

Signed-off-by: Simon Kobyda 
---
 tests/Makefile.am|   8 ++
 tests/vshtabletest.c | 247 +++
 2 files changed, 255 insertions(+)
 create mode 100644 tests/vshtabletest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 302b50e1cd..89c2965d86 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ test_programs = virshtest sockettest \
virhostdevtest \
virnetdevtest \
virtypedparamtest \
+   vshtabletest \
$(NULL)
 
 test_libraries = libshunload.la \
@@ -938,6 +939,13 @@ metadatatest_SOURCES = \
testutils.c testutils.h
 metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
 
+vshtabletest_SOURCES = \
+   vshtabletest.c \
+   testutils.c testutils.h
+vshtabletest_LDADD = \
+   $(LDADDS) \
+   ../tools/libvirt_shell.la
+
 virshtest_SOURCES = \
virshtest.c \
testutils.c testutils.h
diff --git a/tests/vshtabletest.c b/tests/vshtabletest.c
new file mode 100644
index 00..b41a205761
--- /dev/null
+++ b/tests/vshtabletest.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include "testutils.h"
+#include "viralloc.h"
+#include "../tools/vsh-table.h"
+
+static int
+testVshTableNew(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+
+if (vshTableNew(NULL)) {
+fprintf(stderr, "expected failure when passing null to"
+"vshtablenew\n");
+ret = -1;
+}
+
+return ret;
+}
+
+static int
+testVshTableHeader(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = 0;
+char *out;
+const char *exp = "\
+ 1   fedora28   running  \n\
+ 2   rhel7.5running  \n";
+const char *exp2 = "\
+ Id   Name   State\n\
+--\n\
+ 1fedora28   running  \n\
+ 2rhel7.5running  \n";
+
+vshTablePtr table = vshTableNew("Id", "Name", "State",
+NULL); //to ask about return
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+out = vshTablePrintToString(table, false);
+if (virTestCompareToString(exp, out) < 0)
+ret = -1;
+
+VIR_FREE(out);
+out = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp2, out) < 0)
+ret = -1;
+
+ cleanup:
+VIR_FREE(out);
+vshTableFree(table);
+return ret;
+}
+
+static int
+testVshTableNewUnicode(const void *opaque ATTRIBUTE_UNUSED)
+{
+
+int ret = 0;
+char *out;
+
+char *locale = setlocale(LC_CTYPE, NULL);
+if (!setlocale(LC_CTYPE, "en_US.UTF-8"))
+return EXIT_AM_SKIP;
+
+const char *exp = "\
+ Id   ??  ??  \n\
+-\n\
+ 1fedora28  running  \n\
+ 2rhel7.5   running  \n";
+vshTablePtr table;
+
+table = vshTableNew("Id", "??", "??", NULL);
+if (!table)
+goto cleanup;
+
+vshTableRowAppend(table, "1", "fedora28", "running", NULL);
+vshTableRowAppend(table, "2", "rhel7.5", "running",
+  NULL);
+
+out = vshTablePrintToString(table, true);
+if (virTestCompareToString(exp, out) < 0)
+ret = -1;
+
+ cleanup

[libvirt] [PATCH v2 0/3] vsh: Introduce new API for printing tables

2018-08-15 Thread Simon Kobyda
Created new API for priting tables, mainly to solve alignment problems.
Implemented these test to virsh list. In the future, API may be
everywhere in virsh and virt-admin.
Also wrote basic tests for the new API, and corrected tests in virshtest
which are influenced by implementation of the API in virsh list.

Diff to v2:
- added tests
- fixed alignment for unicode character which span more spaces
- moved ncolumns check to vshTableRowAppend
- changed arguments for functions vshTablePrint, vshTablePrintToStdout,
vshTablePrintToString

Simon Kobyda (3):
  vsh: Add API for printing tables.
  virsh: Implement new table API for virsh list
  vsh: Added tests

 tests/Makefile.am|   8 +
 tests/virshtest.c|  14 +-
 tests/vshtabletest.c | 247 +
 tools/Makefile.am|   4 +-
 tools/virsh-domain-monitor.c |  43 ++--
 tools/vsh-table.c| 413 +++
 tools/vsh-table.h|  42 
 7 files changed, 744 insertions(+), 27 deletions(-)
 create mode 100644 tests/vshtabletest.c
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 2/3] virsh: Implement new table API for virsh list

2018-08-15 Thread Simon Kobyda
Instead of printing it straight in virsh, it creates table struct
which is filled with header and rows(domains). It allows us to know
more about table before printing to calculate alignment right.

Signed-off-by: Simon Kobyda 
---
 tests/virshtest.c| 14 ++--
 tools/virsh-domain-monitor.c | 43 
 2 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/tests/virshtest.c b/tests/virshtest.c
index 94548a82d1..10cd0d356b 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -98,9 +98,9 @@ static int testCompareListDefault(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_DEFAULT, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 test   running\n\
+ Id   Name   State\n\
+--\n\
+ 1test   running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
@@ -109,10 +109,10 @@ static int testCompareListCustom(const void *data 
ATTRIBUTE_UNUSED)
 {
   const char *const argv[] = { VIRSH_CUSTOM, "list", NULL };
   const char *exp = "\
- IdName   State\n\
-\n\
- 1 fv0running\n\
- 2 fc4running\n\
+ Id   Name   State\n\
+--\n\
+ 1fv0running  \n\
+ 2fc4running  \n\
 \n";
   return testCompareOutputLit(exp, NULL, argv);
 }
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b4f9739b..adc5bb1a7a 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -39,6 +39,7 @@
 #include "virmacaddr.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 VIR_ENUM_DECL(virshDomainIOError)
 VIR_ENUM_IMPL(virshDomainIOError,
@@ -1901,6 +1902,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
 unsigned int id;
 unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+vshTablePtr table = NULL;
 
 /* construct filter flags */
 if (vshCommandOptBool(cmd, "inactive") ||
@@ -1940,15 +1942,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 /* print table header in legacy mode */
 if (optTable) {
 if (optTitle)
-vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
-  _("Id"), _("Name"), _("State"), _("Title"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Name", "State", "Title", NULL);
 else
-vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
-  _("Id"), _("Name"), _("State"),
-  "-"
-  "---");
+table = vshTableNew("Id", "Name", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->ndomains; i++) {
@@ -1973,20 +1972,22 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 if (optTitle) {
 if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
 goto cleanup;
-
-vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state),
- title);
-
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  title, NULL) < 0)
+goto cleanup;
 VIR_FREE(title);
 } else {
-vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state));
+if (vshTableRowAppend(table, id_buf,
+  virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  NULL) < 0)
+goto cleanup;
 }
+
 } el

Re: [libvirt] [PATCH 1/2] Add API for printing tables.

2018-08-13 Thread Simon Kobyda
On Mon, 2018-08-13 at 12:01 +0200, Michal Prívozník wrote:
> On 08/13/2018 11:46 AM, Simon Kobyda wrote:
> > On Fri, 2018-08-10 at 15:40 +0200, Michal Privoznik wrote:
> > > On 08/10/2018 11:11 AM, Simon Kobyda wrote:
> 
> 
> > > > +static vshTableRowPtr
> > > > +vshTableRowNew(size_t size, const char *arg, va_list ap)
> > > 
> > > I know we discussed this in person, but now that I see this code
> > > and
> > > think about it more I think this @size argument should be dropped
> > > from
> > > this function and the corresponding check should be moved to [1]
> > 
> > That way I will implement identical loop also there [1], to count
> > number of variable arguments to make that check (if there is better
> > way
> > to count number of variable arguments, I'm open to suggestions :)
> > ).
> > Sure I can drop it there, but what are pros of that? I'm curious
> > :).
> 
> I'm not sure why you would need the second loop? The way your code
> works
> right now is that vshTableRowNew must have the sentinel (= args have
> to
> end with NULL). What I am suggesting is for vshTableRowNew() to just
> consume all the args (like it is doing now) until the sentinel. And
> only
> after that check at [1]  whether row->ncells is expected value.
> 
I see, I misunderstood. That's also an option.
> > > 
> > > > +{
> > > > +vshTableRowPtr row = NULL;
> > > > +char *tmp = NULL;
> > > > +
> > > > +if (!arg) {
> > > > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > > +_("Table row cannot be empty"));
> > > > +goto error;
> > > > +}
> > > > +
> > > > +if (VIR_ALLOC(row) < 0)
> > > > +goto error;
> > > > +
> > > > +while (arg) {
> > > > +if (VIR_STRDUP(tmp, arg) < 0)
> > > > +goto error;
> > > > +
> > > > +if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) <
> > > > 0)
> > > > +goto error;
> > > > +
> > > > +arg = va_arg(ap, const char *);
> > > > +}
> > > > +
> > > > +if (size && row->ncells != size) {
> > > > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > > +_("Incorrect number of cells in a
> > > > table
> > > > row"));
> > > > +goto error;
> > > > +}
> > > > +
> > > > +return row;
> > > > +
> > > > + error:
> > > > +vshTableRowFree(row);
> > > > +return NULL;
> > > > +}
> > > > +
> 
> 
> > > > +
> > > > +/**
> > > > + * vshTableRowPrint:
> > > > + * @ctl virtshell control structure
> > > > + * @row: table to append to
> > > > + * @maxwidths: maximum count of characters for each columns
> > > > + * @widths: count of character for each cell in this row
> > > > + * @printCB function for priting table
> > > > + * @buf: buffer to store table (only if @toStdout == true)
> > > > + * @toStdout: whetever print table to Stdout or return in
> > > > buffer
> > > > + */
> > > > +static void
> > > > +vshTableRowPrint(vshControl *ctl,
> > > > + vshTableRowPtr row,
> > > > + size_t *maxwidths,
> > > > + size_t *widths,
> > > > + vshPrintCB printCB,
> > > > + virBufferPtr buf,
> > > > + bool toStdout)
> > > > +{
> > > > +size_t i;
> > > > +size_t j;
> > > > +
> > > > +if (toStdout) {
> > > > +for (i = 0; i < row->ncells; i++) {
> > > > +printCB(ctl, " %s", row->cells[i]);
> > > > +
> > > > +for (j = 0; j < maxwidths[i] - widths[i] + 2; j++)
> > > > +printCB(ctl, " ");
> > > > +}
> > > > +printCB(ctl, "\n");
> > > > +} else {
> > > > +for (i = 0; i < row->ncells; i++) {
> > > > +virBufferAsprintf(buf, " %s", row->cells[i]);
> > > > +
> > > &

Re: [libvirt] [PATCH 1/2] Add API for printing tables.

2018-08-13 Thread Simon Kobyda
On Fri, 2018-08-10 at 15:40 +0200, Michal Privoznik wrote:
> On 08/10/2018 11:11 AM, Simon Kobyda wrote:
> > It solves problems with alignment of columns. Width of each column
> > is calculated by its biggest cell. Should solve unicode bug.
> > In future, it may be implemented in virsh, virt-admin...
> > 
> > This API has 5 public functions:
> > - vshTableNew - adds new table and defines its header
> > - vshTableRowAppend - appends new row (for same number of columns
> > as in
> > header)
> > - vshTablePrintToStdout
> > - vshTablePrintToString
> > - vshTableFree
> > 
> > https://bugzilla.redhat.com/show_bug.cgi?id=1574624
> > https://bugzilla.redhat.com/show_bug.cgi?id=1584630
> > 
> > Signed-off-by: Simon Kobyda 
> > ---
> >  tools/Makefile.am |   4 +-
> >  tools/vsh-table.c | 367
> > ++
> >  tools/vsh-table.h |  42 ++
> >  3 files changed, 412 insertions(+), 1 deletion(-)
> >  create mode 100644 tools/vsh-table.c
> >  create mode 100644 tools/vsh-table.h
> > 
> 
> Missing cover letter. When sending more than one patch it's
> necessary.
> Also the patch should have "vsh: " prefix so that it's obvious what
> part
> of the ever growing source it's touching.
> 
> > diff --git a/tools/Makefile.am b/tools/Makefile.am
> > index 26c887649e..ed23575aa7 100644
> > --- a/tools/Makefile.am
> > +++ b/tools/Makefile.am
> > @@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
> > $(READLINE_LIBS) \
> > ../gnulib/lib/libgnu.la \
> > $(NULL)
> > -libvirt_shell_la_SOURCES = vsh.c vsh.h
> > +libvirt_shell_la_SOURCES = \
> > +   vsh.c vsh.h \
> > +   vsh-table.c vsh-table.h
> >  
> >  virt_host_validate_SOURCES = \
> > virt-host-validate.c \
> > diff --git a/tools/vsh-table.c b/tools/vsh-table.c
> > new file mode 100644
> > index 00..11dc807ba9
> > --- /dev/null
> > +++ b/tools/vsh-table.c
> > @@ -0,0 +1,367 @@
> > +/*
> > + * vsh-table.c: table printing helper
> > + *
> > + * Copyright (C) 2018 Red Hat, Inc.
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later
> > version.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General
> > Public
> > + * License along with this library.  If not, see
> > + * <http://www.gnu.org/licenses/>.
> > + *
> > + * Authors:
> > + *   Simon Kobyda 
> > + *
> > + */
> > +
> > +#include 
> > +#include "vsh-table.h"
> > +#include "virsh-util.h"
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "viralloc.h"
> > +#include "virbuffer.h"
> > +#include "virstring.h"
> 
> Nit pick, we tend to include system headers first and only after that
> the local ones.
> 
> > +
> > +typedef void (*vshPrintCB)(vshControl *ctl, const char *fmt, ...);
> > +
> > +struct _vshTableRow {
> > +char **cells;
> > +size_t ncells;
> > +};
> > +
> > +struct _vshTable {
> > +vshTableRowPtr *rows;
> > +size_t nrows;
> > +};
> > +
> > +static void
> > +vshTableRowFree(vshTableRowPtr row)
> > +{
> > +size_t i;
> > +
> > +if (!row)
> > +return;
> > +
> > +for (i = 0; i < row->ncells; i++)
> > +VIR_FREE(row->cells[i]);
> > +
> > +VIR_FREE(row->cells);
> > +VIR_FREE(row);
> > +}
> > +
> > +void
> > +vshTableFree(vshTablePtr table)
> > +{
> > +size_t i;
> > +
> > +if (!table)
> > +return;
> > +
> > +for (i = 0; i < table->nrows; i++)
> > +vshTableRowFree(table->rows[i]);
> > +VIR_FREE(table->rows);
> > +VIR_FREE(table);
> > +}
> > +
> > +/**
> > + * vshTableRowNew:
> > + * @size: expected number of c

[libvirt] [PATCH 1/2] Add API for printing tables.

2018-08-10 Thread Simon Kobyda
It solves problems with alignment of columns. Width of each column
is calculated by its biggest cell. Should solve unicode bug.
In future, it may be implemented in virsh, virt-admin...

This API has 5 public functions:
- vshTableNew - adds new table and defines its header
- vshTableRowAppend - appends new row (for same number of columns as in
header)
- vshTablePrintToStdout
- vshTablePrintToString
- vshTableFree

https://bugzilla.redhat.com/show_bug.cgi?id=1574624
https://bugzilla.redhat.com/show_bug.cgi?id=1584630

Signed-off-by: Simon Kobyda 
---
 tools/Makefile.am |   4 +-
 tools/vsh-table.c | 367 ++
 tools/vsh-table.h |  42 ++
 3 files changed, 412 insertions(+), 1 deletion(-)
 create mode 100644 tools/vsh-table.c
 create mode 100644 tools/vsh-table.h

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 26c887649e..ed23575aa7 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -144,7 +144,9 @@ libvirt_shell_la_LIBADD = \
$(READLINE_LIBS) \
../gnulib/lib/libgnu.la \
$(NULL)
-libvirt_shell_la_SOURCES = vsh.c vsh.h
+libvirt_shell_la_SOURCES = \
+   vsh.c vsh.h \
+   vsh-table.c vsh-table.h
 
 virt_host_validate_SOURCES = \
virt-host-validate.c \
diff --git a/tools/vsh-table.c b/tools/vsh-table.c
new file mode 100644
index 00..11dc807ba9
--- /dev/null
+++ b/tools/vsh-table.c
@@ -0,0 +1,367 @@
+/*
+ * vsh-table.c: table printing helper
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Simon Kobyda 
+ *
+ */
+
+#include 
+#include "vsh-table.h"
+#include "virsh-util.h"
+
+#include 
+#include 
+#include 
+
+#include "viralloc.h"
+#include "virbuffer.h"
+#include "virstring.h"
+
+typedef void (*vshPrintCB)(vshControl *ctl, const char *fmt, ...);
+
+struct _vshTableRow {
+char **cells;
+size_t ncells;
+};
+
+struct _vshTable {
+vshTableRowPtr *rows;
+size_t nrows;
+};
+
+static void
+vshTableRowFree(vshTableRowPtr row)
+{
+size_t i;
+
+if (!row)
+return;
+
+for (i = 0; i < row->ncells; i++)
+VIR_FREE(row->cells[i]);
+
+VIR_FREE(row->cells);
+VIR_FREE(row);
+}
+
+void
+vshTableFree(vshTablePtr table)
+{
+size_t i;
+
+if (!table)
+return;
+
+for (i = 0; i < table->nrows; i++)
+vshTableRowFree(table->rows[i]);
+VIR_FREE(table->rows);
+VIR_FREE(table);
+}
+
+/**
+ * vshTableRowNew:
+ * @size: expected number of cells in row.
+ * @arg: the first argument.
+ * @ap: list of variadic arguments
+ *
+ * Creates a new row in the table. Each argument passed
+ * represents a cell in the row. If the number of cells is not
+ * equal to @size, then NULL is returned.  However, if @size is
+ * equal to 0, the aforementioned check is suppressed.
+ *
+ * Returns: pointer to vshTableRowPtr row or NULL.
+ */
+static vshTableRowPtr
+vshTableRowNew(size_t size, const char *arg, va_list ap)
+{
+vshTableRowPtr row = NULL;
+char *tmp = NULL;
+
+if (!arg) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Table row cannot be empty"));
+goto error;
+}
+
+if (VIR_ALLOC(row) < 0)
+goto error;
+
+while (arg) {
+if (VIR_STRDUP(tmp, arg) < 0)
+goto error;
+
+if (VIR_APPEND_ELEMENT(row->cells, row->ncells, tmp) < 0)
+goto error;
+
+arg = va_arg(ap, const char *);
+}
+
+if (size && row->ncells != size) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Incorrect number of cells in a table row"));
+goto error;
+}
+
+return row;
+
+ error:
+vshTableRowFree(row);
+return NULL;
+}
+
+/**
+ * vshTableNew:
+ * @arg: List of column names (NULL terminated)
+ *
+ * Creates a new table.
+ *
+ * Returns: pointer to table or NULL.
+ */
+vshTablePtr
+vshTableNew(const char *arg, ...)
+{
+vshTablePtr table;
+vshTableRowPtr header = NULL;
+va_list ap;
+
+if (VIR_ALLOC(table) < 0)
+goto error;
+
+va_start(ap, arg);
+header = vshTableRowNew(0, arg, ap);
+va_end(ap);
+

[libvirt] [PATCH 2/2] virsh: Implement new table API for virsh list

2018-08-10 Thread Simon Kobyda
Instead of printing it straight in virsh, it creates table struct
which is filled with header and rows(domains). It allows us to know
more about table before printing to calculate alignment right.

Signed-off-by: Simon Kobyda 
---
 tools/virsh-domain-monitor.c | 39 ++--
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index b9b4f9739b..f6842877f5 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -39,6 +39,7 @@
 #include "virmacaddr.h"
 #include "virxml.h"
 #include "virstring.h"
+#include "vsh-table.h"
 
 VIR_ENUM_DECL(virshDomainIOError)
 VIR_ENUM_IMPL(virshDomainIOError,
@@ -1901,6 +1902,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
 unsigned int id;
 unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+vshTablePtr table = NULL;
 
 /* construct filter flags */
 if (vshCommandOptBool(cmd, "inactive") ||
@@ -1940,15 +1942,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 /* print table header in legacy mode */
 if (optTable) {
 if (optTitle)
-vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
-  _("Id"), _("Name"), _("State"), _("Title"),
-  "-"
-  "-");
+table = vshTableNew("Id", "Name", "State", "Title", NULL);
 else
-vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
-  _("Id"), _("Name"), _("State"),
-  "-"
-  "---");
+table = vshTableNew("Id", "Name", "State", NULL);
+
+if (!table)
+goto cleanup;
 }
 
 for (i = 0; i < list->ndomains; i++) {
@@ -1973,20 +1972,18 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 if (optTitle) {
 if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
 goto cleanup;
-
-vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state),
- title);
-
+vshTableRowAppend(table, id_buf, virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  title, NULL);
 VIR_FREE(title);
 } else {
-vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
- virDomainGetName(dom),
- state == -2 ? _("saved")
- : virshDomainStateToString(state));
+vshTableRowAppend(table, id_buf, virDomainGetName(dom),
+  state == -2 ? _("saved")
+  : virshDomainStateToString(state),
+  NULL);
 }
+
 } else if (optUUID && optName) {
 if (virDomainGetUUIDString(dom, uuid) < 0) {
 vshError(ctl, "%s", _("Failed to get domain's UUID"));
@@ -2004,8 +2001,12 @@ cmdList(vshControl *ctl, const vshCmd *cmd)
 }
 }
 
+if (optTable)
+vshTablePrintToStdout(ctl, table);
+
 ret = true;
  cleanup:
+vshTableFree(table);
 virshDomainListFree(list);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v3] conf: virDomainDefValidateInternal prohibit some characters in shmem name

2018-08-05 Thread Simon Kobyda
Validate that the provided XML shmem name is not directory specific "."
or ".." names as well as ensuring that there is no path separator '/' in
the name.

https://bugzilla.redhat.com/show_bug.cgi?id=1192400

Signed-off-by: Simon Kobyda 
---
Changes in v3:
- moved the functionality to virDomainDeviceDefValidateInternal
- documented changes in docs/formatdomain.html.in

 docs/formatdomain.html.in |  4 +++-
 src/conf/domain_conf.c| 29 -
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a3afe137bf..f18ca6fc64 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -8017,7 +8017,9 @@ qemu-kvm -net nic,model=? /dev/null
 shmem
 
   The shmem element has one mandatory attribute,
-  name to identify the shared memory.
+  name to identify the shared memory. This attribute cannot
+  be directory specific to . or .. as well as
+  it cannot involve path separator /.
 
 model
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7ab2953d83..415c03c56f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5696,6 +5696,31 @@ virDomainVsockDefValidate(const virDomainVsockDef *vsock)
 }
 
 
+static int
+virDomainShmemDefValidate(const virDomainShmemDef *shmem)
+{
+if (strchr(shmem->name, '/')) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("shmem name cannot include '/' character"));
+return -1;
+}
+
+if (STREQ(shmem->name, ".")) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("shmem name cannot be equal to '.'"));
+return -1;
+}
+
+if (STREQ(shmem->name, "..")) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("shmem name cannot be equal to '..'"));
+return -1;
+}
+
+return 0;
+}
+
+
 static int
 virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
const virDomainDef *def)
@@ -5734,6 +5759,9 @@ virDomainDeviceDefValidateInternal(const 
virDomainDeviceDef *dev,
 case VIR_DOMAIN_DEVICE_VSOCK:
 return virDomainVsockDefValidate(dev->data.vsock);
 
+case VIR_DOMAIN_DEVICE_SHMEM:
+return virDomainShmemDefValidate(dev->data.shmem);
+
 case VIR_DOMAIN_DEVICE_LEASE:
 case VIR_DOMAIN_DEVICE_FS:
 case VIR_DOMAIN_DEVICE_INPUT:
@@ -5743,7 +5771,6 @@ virDomainDeviceDefValidateInternal(const 
virDomainDeviceDef *dev,
 case VIR_DOMAIN_DEVICE_HUB:
 case VIR_DOMAIN_DEVICE_MEMBALLOON:
 case VIR_DOMAIN_DEVICE_NVRAM:
-case VIR_DOMAIN_DEVICE_SHMEM:
 case VIR_DOMAIN_DEVICE_TPM:
 case VIR_DOMAIN_DEVICE_PANIC:
 case VIR_DOMAIN_DEVICE_IOMMU:
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] New virsh feature: domif-setlink --domain --interface --state completer

2018-07-16 Thread Simon Kobyda
After you go through command mentioned above, completer finds
what state the device is currently in, and suggests an opposite state.
---
 tools/virsh-completer.c | 73 -
 tools/virsh-completer.h |  4 +++
 tools/virsh-domain.c|  1 +
 3 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index 2327e08340..e32fd82211 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -32,6 +32,7 @@
 #include "internal.h"
 #include "virutil.h"
 #include "viralloc.h"
+#include "virmacaddr.h"
 #include "virstring.h"
 #include "virxml.h"
 
@@ -750,7 +751,6 @@ virshDomainEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 return NULL;
 }
 
-
 char **
 virshPoolEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
 const vshCmd *cmd ATTRIBUTE_UNUSED,
@@ -776,6 +776,77 @@ virshPoolEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 return NULL;
 }
 
+char **
+virshDomainInterfaceStateCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
+const vshCmd *cmd ATTRIBUTE_UNUSED,
+unsigned int flags)
+{
+virshControlPtr priv = ctl->privData;
+const char *iface = NULL;
+char **ret = NULL;
+xmlDocPtr xml = NULL;
+virMacAddr macaddr;
+char *state = NULL;
+char *xpath = NULL;
+char macstr[18] = "";
+xmlXPathContextPtr ctxt = NULL;
+xmlNodePtr *interfaces = NULL;
+int ninterfaces;
+
+virCheckFlags(0, NULL);
+
+if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
+return NULL;
+
+if (vshCommandOptStringReq(ctl, cmd, "interface", ) < 0)
+goto cleanup;
+
+if (virshDomainGetXML(ctl, cmd, flags, , ) < 0)
+goto cleanup;
+
+/* normalize the mac addr */
+if (virMacAddrParse(iface, ) == 0)
+virMacAddrFormat(, macstr);
+
+if (virAsprintf(, "/domain/devices/interface[(mac/@address = '%s') 
or "
+"  (target/@dev = '%s')]",
+   macstr, iface) < 0)
+goto cleanup;
+
+if ((ninterfaces = virXPathNodeSet(xpath, ctxt, )) < 0)
+goto cleanup;
+
+if (ninterfaces != 1)
+goto cleanup;
+
+ctxt->node = interfaces[0];
+
+if (VIR_ALLOC_N(ret, 2) < 0)
+goto error;
+
+if ((state = virXPathString("string(./link/@state)", ctxt)) &&
+STREQ(state, "down")) {
+if (VIR_STRDUP(ret[0], "up") < 0)
+goto error;
+} else {
+if (VIR_STRDUP(ret[0], "down") < 0)
+goto error;
+}
+
+ cleanup:
+VIR_FREE(state);
+VIR_FREE(interfaces);
+VIR_FREE(xpath);
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+return ret;
+
+ error:
+virStringListFree(ret);
+ret = NULL;
+goto cleanup;
+}
+
 
 char **
 virshNodedevEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h
index 1c14bb2a54..b4fd2a86c6 100644
--- a/tools/virsh-completer.h
+++ b/tools/virsh-completer.h
@@ -94,6 +94,10 @@ char ** virshPoolEventNameCompleter(vshControl *ctl,
 const vshCmd *cmd,
 unsigned int flags);
 
+char ** virshDomainInterfaceStateCompleter(vshControl *ctl,
+   const vshCmd *cmd,
+   unsigned int flags);
+
 char ** virshNodedevEventNameCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags);
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 3959b5475b..8adec1d9b1 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -3064,6 +3064,7 @@ static const vshCmdOptDef opts_domif_setlink[] = {
 {.name = "state",
  .type = VSH_OT_DATA,
  .flags = VSH_OFLAG_REQ,
+ .completer = virshDomainInterfaceStateCompleter,
  .help = N_("new state of the device")
 },
 {.name = "persistent",
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2] New virsh feature: domif-setlink --domain --interface --state completer

2018-07-12 Thread Simon Kobyda
After you go through command mentioned above, completer
finds what state the device is currently in, and suggests
an opposite state.

Signed-off-by: Simon Kobyda 
---

Changes in V2:
- Added "Signed-off-by"
- Changed format of commit message to make it more
readable

 tools/virsh-completer.c | 73 -
 tools/virsh-completer.h |  4 +++
 tools/virsh-domain.c|  1 +
 3 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index 2327e08340..e32fd82211 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -32,6 +32,7 @@
 #include "internal.h"
 #include "virutil.h"
 #include "viralloc.h"
+#include "virmacaddr.h"
 #include "virstring.h"
 #include "virxml.h"
 
@@ -750,7 +751,6 @@ virshDomainEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 return NULL;
 }
 
-
 char **
 virshPoolEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
 const vshCmd *cmd ATTRIBUTE_UNUSED,
@@ -776,6 +776,77 @@ virshPoolEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 return NULL;
 }
 
+char **
+virshDomainInterfaceStateCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
+const vshCmd *cmd ATTRIBUTE_UNUSED,
+unsigned int flags)
+{
+virshControlPtr priv = ctl->privData;
+const char *iface = NULL;
+char **ret = NULL;
+xmlDocPtr xml = NULL;
+virMacAddr macaddr;
+char *state = NULL;
+char *xpath = NULL;
+char macstr[18] = "";
+xmlXPathContextPtr ctxt = NULL;
+xmlNodePtr *interfaces = NULL;
+int ninterfaces;
+
+virCheckFlags(0, NULL);
+
+if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
+return NULL;
+
+if (vshCommandOptStringReq(ctl, cmd, "interface", ) < 0)
+goto cleanup;
+
+if (virshDomainGetXML(ctl, cmd, flags, , ) < 0)
+goto cleanup;
+
+/* normalize the mac addr */
+if (virMacAddrParse(iface, ) == 0)
+virMacAddrFormat(, macstr);
+
+if (virAsprintf(, "/domain/devices/interface[(mac/@address = '%s') 
or "
+"  (target/@dev = '%s')]",
+   macstr, iface) < 0)
+goto cleanup;
+
+if ((ninterfaces = virXPathNodeSet(xpath, ctxt, )) < 0)
+goto cleanup;
+
+if (ninterfaces != 1)
+goto cleanup;
+
+ctxt->node = interfaces[0];
+
+if (VIR_ALLOC_N(ret, 2) < 0)
+goto error;
+
+if ((state = virXPathString("string(./link/@state)", ctxt)) &&
+STREQ(state, "down")) {
+if (VIR_STRDUP(ret[0], "up") < 0)
+goto error;
+} else {
+if (VIR_STRDUP(ret[0], "down") < 0)
+goto error;
+}
+
+ cleanup:
+VIR_FREE(state);
+VIR_FREE(interfaces);
+VIR_FREE(xpath);
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+return ret;
+
+ error:
+virStringListFree(ret);
+ret = NULL;
+goto cleanup;
+}
+
 
 char **
 virshNodedevEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h
index 1c14bb2a54..b4fd2a86c6 100644
--- a/tools/virsh-completer.h
+++ b/tools/virsh-completer.h
@@ -94,6 +94,10 @@ char ** virshPoolEventNameCompleter(vshControl *ctl,
 const vshCmd *cmd,
 unsigned int flags);
 
+char ** virshDomainInterfaceStateCompleter(vshControl *ctl,
+   const vshCmd *cmd,
+   unsigned int flags);
+
 char ** virshNodedevEventNameCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags);
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 3959b5475b..8adec1d9b1 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -3064,6 +3064,7 @@ static const vshCmdOptDef opts_domif_setlink[] = {
 {.name = "state",
  .type = VSH_OT_DATA,
  .flags = VSH_OFLAG_REQ,
+ .completer = virshDomainInterfaceStateCompleter,
  .help = N_("new state of the device")
 },
 {.name = "persistent",
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2] completer: Doesn't alloc enough space for null terminated array of strings

2018-07-12 Thread Simon Kobyda
Functions virshSecretEventNameCompleter, virshPoolEventNameCompleter,
virshNodedevEventNameCompleter allocates only enough space
for array of N strings.

However these are null terminated strings, so program needs to
alloc space for array of N+1 strings.

How to replicate error: valgrind virsh, use completer for
'-nodedev-event --event' or '-pool-event --event' or
'-secret-event --event'.

Signed-off-by: Simon Kobyda 

---

Changes in V2:
- Added "Signed-off-by"
- Changed format of commit message to make it more
readable

 tools/virsh-completer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index 2327e08340..be59ea2e82 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -709,7 +709,7 @@ virshSecretEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 
 virCheckFlags(0, NULL);
 
-if (VIR_ALLOC_N(ret, VIR_SECRET_EVENT_ID_LAST) < 0)
+if (VIR_ALLOC_N(ret, VIR_SECRET_EVENT_ID_LAST + 1) < 0)
 goto error;
 
 for (i = 0; i < VIR_SECRET_EVENT_ID_LAST; i++) {
@@ -761,7 +761,7 @@ virshPoolEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 
 virCheckFlags(0, NULL);
 
-if (VIR_ALLOC_N(ret, VIR_STORAGE_POOL_EVENT_ID_LAST) < 0)
+if (VIR_ALLOC_N(ret, VIR_STORAGE_POOL_EVENT_ID_LAST + 1) < 0)
 goto error;
 
 for (i = 0; i < VIR_STORAGE_POOL_EVENT_ID_LAST; i++) {
@@ -787,7 +787,7 @@ virshNodedevEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 
 virCheckFlags(0, NULL);
 
-if (VIR_ALLOC_N(ret, VIR_NODE_DEVICE_EVENT_ID_LAST) < 0)
+if (VIR_ALLOC_N(ret, VIR_NODE_DEVICE_EVENT_ID_LAST + 1) < 0)
 goto error;
 
 for (i = 0; i < VIR_NODE_DEVICE_EVENT_ID_LAST; i++) {
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2] conf: virDomainDefValidateInternal prohibit some characters in shmem name

2018-07-12 Thread Simon Kobyda
Signed-off-by: Simon Kobyda 

On Thu, Jul 12, 2018 at 3:10 PM Simon Kobyda  wrote:

> XML shmem name will not include character '/', and will not be equal to
> strings
> "." or "..", as shmem name is used in a path.
>
> https://bugzilla.redhat.com/show_bug.cgi?id=1192400
> ---
>
> Changes in V2
> - Added error reports
> - Error situation will happen only if shmem name is equal to
>   "." or "..", however their occurence in a name compromised of
> more
>   characters is allowed.
>
>  src/conf/domain_conf.c | 22 ++
>  1 file changed, 22 insertions(+)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 7ab2953d83..6b34c17de4 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -6107,6 +6107,8 @@ virDomainDefLifecycleActionValidate(const
> virDomainDef *def)
>  static int
>  virDomainDefValidateInternal(const virDomainDef *def)
>  {
> +size_t i;
> +
>  if (virDomainDefCheckDuplicateDiskInfo(def) < 0)
>  return -1;
>
> @@ -6136,6 +6138,26 @@ virDomainDefValidateInternal(const virDomainDef
> *def)
>  return -1;
>  }
>
> +for (i = 0; i < def->nshmems; i++) {
> +if (strchr(def->shmems[i]->name, '/')) {
> +virReportError(VIR_ERR_XML_ERROR, "%s",
> +   _("shmem name cannot include '/' character"));
> +return -1;
> +}
> +
> +if (STREQ(def->shmems[i]->name, ".")) {
> +virReportError(VIR_ERR_XML_ERROR, "%s",
> +   _("shmem name cannot be equal to '.'"));
> +return -1;
> +}
> +
> +if (STREQ(def->shmems[i]->name, "..")) {
> +virReportError(VIR_ERR_XML_ERROR, "%s",
> +   _("shmem name cannot be equal to '..'"));
> +return -1;
> +}
> +}
> +
>  if (virDomainDefLifecycleActionValidate(def) < 0)
>  return -1;
>
> --
> 2.17.1
>
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2] conf: virDomainDefValidateInternal prohibit some characters in shmem name

2018-07-12 Thread Simon Kobyda
XML shmem name will not include character '/', and will not be equal to strings
"." or "..", as shmem name is used in a path.

https://bugzilla.redhat.com/show_bug.cgi?id=1192400
---

Changes in V2 
- Added error reports
- Error situation will happen only if shmem name is equal to
  "." or "..", however their occurence in a name compromised of more
  characters is allowed.

 src/conf/domain_conf.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7ab2953d83..6b34c17de4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6107,6 +6107,8 @@ virDomainDefLifecycleActionValidate(const virDomainDef 
*def)
 static int
 virDomainDefValidateInternal(const virDomainDef *def)
 {
+size_t i;
+
 if (virDomainDefCheckDuplicateDiskInfo(def) < 0)
 return -1;
 
@@ -6136,6 +6138,26 @@ virDomainDefValidateInternal(const virDomainDef *def)
 return -1;
 }
 
+for (i = 0; i < def->nshmems; i++) {
+if (strchr(def->shmems[i]->name, '/')) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("shmem name cannot include '/' character"));
+return -1;
+}
+
+if (STREQ(def->shmems[i]->name, ".")) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("shmem name cannot be equal to '.'"));
+return -1;
+}
+
+if (STREQ(def->shmems[i]->name, "..")) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("shmem name cannot be equal to '..'"));
+return -1;
+}
+}
+
 if (virDomainDefLifecycleActionValidate(def) < 0)
 return -1;
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] completer: Doesn't alloc enough space for null terminated array of strings

2018-07-12 Thread Simon Kobyda
Functions virshSecretEventNameCompleter, virshPoolEventNameCompleter, 
virshNodedevEventNameCompleter allocates only enough space for array of N 
strings.
However these are null terminated strings, so program needs to alloc 
space for array of N+1 strings.
How to replicate error: valgrind virsh, use completer for 
'-nodedev-event --event' or '-pool-event --event' or '-secret-event --event'.
---
 tools/virsh-completer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index 2327e08340..be59ea2e82 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -709,7 +709,7 @@ virshSecretEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 
 virCheckFlags(0, NULL);
 
-if (VIR_ALLOC_N(ret, VIR_SECRET_EVENT_ID_LAST) < 0)
+if (VIR_ALLOC_N(ret, VIR_SECRET_EVENT_ID_LAST + 1) < 0)
 goto error;
 
 for (i = 0; i < VIR_SECRET_EVENT_ID_LAST; i++) {
@@ -761,7 +761,7 @@ virshPoolEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 
 virCheckFlags(0, NULL);
 
-if (VIR_ALLOC_N(ret, VIR_STORAGE_POOL_EVENT_ID_LAST) < 0)
+if (VIR_ALLOC_N(ret, VIR_STORAGE_POOL_EVENT_ID_LAST + 1) < 0)
 goto error;
 
 for (i = 0; i < VIR_STORAGE_POOL_EVENT_ID_LAST; i++) {
@@ -787,7 +787,7 @@ virshNodedevEventNameCompleter(vshControl *ctl 
ATTRIBUTE_UNUSED,
 
 virCheckFlags(0, NULL);
 
-if (VIR_ALLOC_N(ret, VIR_NODE_DEVICE_EVENT_ID_LAST) < 0)
+if (VIR_ALLOC_N(ret, VIR_NODE_DEVICE_EVENT_ID_LAST + 1) < 0)
 goto error;
 
 for (i = 0; i < VIR_NODE_DEVICE_EVENT_ID_LAST; i++) {
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] conf: virDomainDefValidateInternal prohibit some characters in shmem name

2018-07-10 Thread Simon Kobyda
XML shmem name will not include characters '/', '.' or '..', as shmem name
is used in a path
https://bugzilla.redhat.com/show_bug.cgi?id=1192400
---
 src/conf/domain_conf.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7ab2953d83..3f580525bb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6107,6 +6107,8 @@ virDomainDefLifecycleActionValidate(const virDomainDef 
*def)
 static int
 virDomainDefValidateInternal(const virDomainDef *def)
 {
+size_t i;
+
 if (virDomainDefCheckDuplicateDiskInfo(def) < 0)
 return -1;
 
@@ -6136,6 +6138,17 @@ virDomainDefValidateInternal(const virDomainDef *def)
 return -1;
 }
 
+for (i = 0; i < def->nshmems; i++) {
+if (strchr(def->shmems[i]->name, '/'))
+return -1;
+
+if (strchr(def->shmems[i]->name, '.'))
+return -1;
+
+if (strstr(def->shmems[i]->name, ".."))
+return -1;
+}
+
 if (virDomainDefLifecycleActionValidate(def) < 0)
 return -1;
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list