John Eckersberg
2012-Nov-01 16:17 UTC
[Libguestfs] [PATCH 0/2] New inspect_list_applications2 API
Here's the new API method and update to virt-inspector. I still need to implement app_arch for debian and windows (if applicable), for now they just return empty strings.
John Eckersberg
2012-Nov-01 16:17 UTC
[Libguestfs] [PATCH 1/2] lib: Add inspect_list_applications2 method (RHBZ#859949)
--- generator/actions.ml | 121 +++++++++++++++++++++++++++++++ generator/structs.ml | 24 ++++++ gobject/Makefile.inc | 2 + java/Makefile.inc | 1 + java/com/redhat/et/libguestfs/.gitignore | 1 + po/POTFILES | 1 + src/inspect-apps.c | 106 +++++++++++++++++++-------- 7 files changed, 226 insertions(+), 30 deletions(-) diff --git a/generator/actions.ml b/generator/actions.ml index 71aee37..8b0124c 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -1523,6 +1523,105 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; style = RStructList ("applications", "application"), [Device "root"], []; shortdesc = "get list of applications installed in the operating system"; longdesc = "\ +I<This call is deprecated>; use C<guestfs_inspect_list_applications2> instead. + +Return the list of applications installed in the operating system. + +I<Note:> This call works differently from other parts of the +inspection API. You have to call C<guestfs_inspect_os>, then +C<guestfs_inspect_get_mountpoints>, then mount up the disks, +before calling this. Listing applications is a significantly +more difficult operation which requires access to the full +filesystem. Also note that unlike the other +C<guestfs_inspect_get_*> calls which are just returning +data cached in the libguestfs handle, this call actually reads +parts of the mounted filesystems during the call. + +This returns an empty list if the inspection code was not able +to determine the list of applications. + +The application structure contains the following fields: + +=over 4 + +=item C<app_name> + +The name of the application. For Red Hat-derived and Debian-derived +Linux guests, this is the package name. + +=item C<app_display_name> + +The display name of the application, sometimes localized to the +install language of the guest operating system. + +If unavailable this is returned as an empty string C<\"\">. +Callers needing to display something can use C<app_name> instead. + +=item C<app_epoch> + +For package managers which use epochs, this contains the epoch of +the package (an integer). If unavailable, this is returned as C<0>. + +=item C<app_version> + +The version string of the application or package. If unavailable +this is returned as an empty string C<\"\">. + +=item C<app_release> + +The release string of the application or package, for package +managers that use this. If unavailable this is returned as an +empty string C<\"\">. + +=item C<app_install_path> + +The installation path of the application (on operating systems +such as Windows which use installation paths). This path is +in the format used by the guest operating system, it is not +a libguestfs path. + +If unavailable this is returned as an empty string C<\"\">. + +=item C<app_trans_path> + +The install path translated into a libguestfs path. +If unavailable this is returned as an empty string C<\"\">. + +=item C<app_publisher> + +The name of the publisher of the application, for package +managers that use this. If unavailable this is returned +as an empty string C<\"\">. + +=item C<app_url> + +The URL (eg. upstream URL) of the application. +If unavailable this is returned as an empty string C<\"\">. + +=item C<app_source_package> + +For packaging systems which support this, the name of the source +package. If unavailable this is returned as an empty string C<\"\">. + +=item C<app_summary> + +A short (usually one line) description of the application or package. +If unavailable this is returned as an empty string C<\"\">. + +=item C<app_description> + +A longer description of the application or package. +If unavailable this is returned as an empty string C<\"\">. + +=back + +Please read L<guestfs(3)/INSPECTION> for more details." }; + + { defaults with + name = "inspect_list_applications2"; + style = RStructList ("applications2", "application2"), [Device "root"], []; + shortdesc = "get list of applications installed in the operating system"; + longdesc = "\ Return the list of applications installed in the operating system. I<Note:> This call works differently from other parts of the @@ -1571,6 +1670,12 @@ The release string of the application or package, for package managers that use this. If unavailable this is returned as an empty string C<\"\">. +=item C<app_arch> + +The architecture string of the application or package, for package +managers that use this. If unavailable this is returned as an empty +string C<\"\">. + =item C<app_install_path> The installation path of the application (on operating systems @@ -1611,6 +1716,22 @@ If unavailable this is returned as an empty string C<\"\">. A longer description of the application or package. If unavailable this is returned as an empty string C<\"\">. +=item C<app_spare1> + +Reserved for future use. + +=item C<app_spare2> + +Reserved for future use. + +=item C<app_spare3> + +Reserved for future use. + +=item C<app_spare4> + +Reserved for future use. + =back Please read L<guestfs(3)/INSPECTION> for more details." }; diff --git a/generator/structs.ml b/generator/structs.ml index 4dcb2c9..fcdafcd 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -230,6 +230,30 @@ let structs = [ ]; s_camel_name = "Application" }; + (* Application v2. *) + { defaults with + s_name = "application2"; + s_cols = [ + "app_name", FString; + "app_display_name", FString; + "app_epoch", FInt32; + "app_version", FString; + "app_release", FString; + "app_arch", FString; + "app_install_path", FString; + "app_trans_path", FString; + "app_publisher", FString; + "app_url", FString; + "app_source_package", FString; + "app_summary", FString; + "app_description", FString; + "app_spare1", FString; + "app_spare2", FString; + "app_spare3", FString; + "app_spare4", FString; + ]; + s_camel_name = "Application2" }; + (* ISO primary volume descriptor. *) { defaults with s_name = "isoinfo"; diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc index 95a4b6b..8708994 100644 --- a/gobject/Makefile.inc +++ b/gobject/Makefile.inc @@ -35,6 +35,7 @@ guestfs_gobject_headers= \ include/guestfs-gobject/struct-inotify_event.h \ include/guestfs-gobject/struct-partition.h \ include/guestfs-gobject/struct-application.h \ + include/guestfs-gobject/struct-application2.h \ include/guestfs-gobject/struct-isoinfo.h \ include/guestfs-gobject/struct-mdstat.h \ include/guestfs-gobject/struct-btrfssubvolume.h \ @@ -99,6 +100,7 @@ guestfs_gobject_sources= \ src/struct-inotify_event.c \ src/struct-partition.c \ src/struct-application.c \ + src/struct-application2.c \ src/struct-isoinfo.c \ src/struct-mdstat.c \ src/struct-btrfssubvolume.c \ diff --git a/java/Makefile.inc b/java/Makefile.inc index 64b533a..9dd39de 100644 --- a/java/Makefile.inc +++ b/java/Makefile.inc @@ -21,6 +21,7 @@ java_built_sources = \ com/redhat/et/libguestfs/Application.java \ + com/redhat/et/libguestfs/Application2.java \ com/redhat/et/libguestfs/BTRFSSubvolume.java \ com/redhat/et/libguestfs/Dirent.java \ com/redhat/et/libguestfs/HivexNode.java \ diff --git a/java/com/redhat/et/libguestfs/.gitignore b/java/com/redhat/et/libguestfs/.gitignore index 72a1144..00bcec9 100644 --- a/java/com/redhat/et/libguestfs/.gitignore +++ b/java/com/redhat/et/libguestfs/.gitignore @@ -1,4 +1,5 @@ Application.java +Application2.java BTRFSSubvolume.java Dirent.java HivexNode.java diff --git a/po/POTFILES b/po/POTFILES index 3f49a05..ba9c9d9 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -181,6 +181,7 @@ gobject/src/optargs-xfs_growfs.c gobject/src/optargs-xfs_repair.c gobject/src/session.c gobject/src/struct-application.c +gobject/src/struct-application2.c gobject/src/struct-btrfssubvolume.c gobject/src/struct-dirent.c gobject/src/struct-hivex_node.c diff --git a/src/inspect-apps.c b/src/inspect-apps.c index 23e68e4..f96b475 100644 --- a/src/inspect-apps.c +++ b/src/inspect-apps.c @@ -42,24 +42,61 @@ #include "guestfs_protocol.h" #ifdef DB_DUMP -static struct guestfs_application_list *list_applications_rpm (guestfs_h *g, struct inspect_fs *fs); +static struct guestfs_application2_list *list_applications_rpm (guestfs_h *g, struct inspect_fs *fs); #endif -static struct guestfs_application_list *list_applications_deb (guestfs_h *g, struct inspect_fs *fs); -static struct guestfs_application_list *list_applications_windows (guestfs_h *g, struct inspect_fs *fs); -static void add_application (guestfs_h *g, struct guestfs_application_list *, const char *name, const char *display_name, int32_t epoch, const char *version, const char *release, const char *install_path, const char *publisher, const char *url, const char *description); -static void sort_applications (struct guestfs_application_list *); +static struct guestfs_application2_list *list_applications_deb (guestfs_h *g, struct inspect_fs *fs); +static struct guestfs_application2_list *list_applications_windows (guestfs_h *g, struct inspect_fs *fs); +static void add_application (guestfs_h *g, struct guestfs_application2_list *, const char *name, const char *display_name, int32_t epoch, const char *version, const char *release, const char *arch, const char *install_path, const char *publisher, const char *url, const char *description); +static void sort_applications (struct guestfs_application2_list *); + +struct guestfs_application_list* +guestfs__inspect_list_applications (guestfs_h *g, const char *root) +{ + struct guestfs_application_list *ret; + struct guestfs_application2_list *r; + size_t i; + + /* Call the new function. */ + r = guestfs_inspect_list_applications2 (g, root); + if (!r) + return NULL; + + /* Translate the structures from the new format to the old format. */ + ret = safe_malloc (g, sizeof (struct guestfs_application_list)); + ret->len = r->len; + ret->val + safe_malloc (g, sizeof (struct guestfs_application) * r->len); + for (i = 0; i < r->len; ++i) { + ret->val[i].app_name = r->val[i].app_name; + ret->val[i].app_display_name = r->val[i].app_display_name; + ret->val[i].app_epoch = r->val[i].app_epoch; + ret->val[i].app_version = r->val[i].app_version; + ret->val[i].app_release = r->val[i].app_release; + ret->val[i].app_install_path = r->val[i].app_install_path; + ret->val[i].app_trans_path = r->val[i].app_trans_path; + ret->val[i].app_publisher = r->val[i].app_publisher; + ret->val[i].app_url = r->val[i].app_url; + ret->val[i].app_source_package = r->val[i].app_source_package; + ret->val[i].app_summary = r->val[i].app_summary; + ret->val[i].app_description = r->val[i].app_description; + } + free (r->val); /* Must not free the strings. */ + free (r); + + return ret; +} /* Unlike the simple inspect-get-* calls, this one assumes that the * disks are mounted up, and reads files from the mounted disks. */ -struct guestfs_application_list * -guestfs__inspect_list_applications (guestfs_h *g, const char *root) +struct guestfs_application2_list * +guestfs__inspect_list_applications2 (guestfs_h *g, const char *root) { struct inspect_fs *fs = guestfs___search_for_root (g, root); if (!fs) return NULL; - struct guestfs_application_list *ret = NULL; + struct guestfs_application2_list *ret = NULL; /* Presently we can only list applications for installed disks. It * is possible in future to get lists of packages from installers. @@ -189,6 +226,7 @@ read_rpm_name (guestfs_h *g, /* tag constants, see rpmtag.h in RPM for complete list */ #define RPMTAG_VERSION 1001 #define RPMTAG_RELEASE 1002 +#define RPMTAG_ARCH 1022 static char * get_rpm_header_tag (guestfs_h *g, const unsigned char *header_start, @@ -233,7 +271,7 @@ get_rpm_header_tag (guestfs_h *g, const unsigned char *header_start, struct read_package_data { struct rpm_names_list *list; - struct guestfs_application_list *apps; + struct guestfs_application2_list *apps; }; static int @@ -244,7 +282,7 @@ read_package (guestfs_h *g, { struct read_package_data *data = datav; struct rpm_name nkey, *entry; - char *version, *release; + char *version, *release, *arch; /* This function reads one (key, value) pair from the Packages * database. The key is the link field (see struct rpm_name). The @@ -271,24 +309,26 @@ read_package (guestfs_h *g, version = get_rpm_header_tag (g, value, valuelen, RPMTAG_VERSION); release = get_rpm_header_tag (g, value, valuelen, RPMTAG_RELEASE); + arch = get_rpm_header_tag (g, value, valuelen, RPMTAG_ARCH); /* Add the application and what we know. */ if (version && release) add_application (g, data->apps, entry->name, "", 0, version, release, - "", "", "", ""); + arch ? arch : "", "", "", "", ""); free (version); free (release); + free (arch); return 0; } -static struct guestfs_application_list * +static struct guestfs_application2_list * list_applications_rpm (guestfs_h *g, struct inspect_fs *fs) { char *Name = NULL, *Packages = NULL; struct rpm_names_list list = { .names = NULL, .len = 0 }; - struct guestfs_application_list *apps = NULL; + struct guestfs_application2_list *apps = NULL; struct read_package_data data; Name = guestfs___download_to_tmp (g, fs, @@ -332,14 +372,14 @@ list_applications_rpm (guestfs_h *g, struct inspect_fs *fs) free (Packages); free_rpm_names_list (&list); if (apps != NULL) - guestfs_free_application_list (apps); + guestfs_free_application2_list (apps); return NULL; } #endif /* defined DB_DUMP */ -static struct guestfs_application_list * +static struct guestfs_application2_list * list_applications_deb (guestfs_h *g, struct inspect_fs *fs) { char *status = NULL; @@ -348,7 +388,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs) if (status == NULL) return NULL; - struct guestfs_application_list *apps = NULL, *ret = NULL; + struct guestfs_application2_list *apps = NULL, *ret = NULL; FILE *fp = NULL; char line[1024]; size_t len; @@ -403,7 +443,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs) else if (STREQ (line, "")) { if (installed_flag && name && version) add_application (g, apps, name, "", 0, version, release ? : "", - "", "", "", ""); + "", "", "", "", ""); free (name); free (version); free (release); @@ -423,7 +463,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs) out: if (ret == NULL && apps != NULL) - guestfs_free_application_list (apps); + guestfs_free_application2_list (apps); if (fp) fclose (fp); free (name); @@ -433,9 +473,9 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs) return ret; } -static void list_applications_windows_from_path (guestfs_h *g, struct guestfs_application_list *apps, const char **path, size_t path_len); +static void list_applications_windows_from_path (guestfs_h *g, struct guestfs_application2_list *apps, const char **path, size_t path_len); -static struct guestfs_application_list * +static struct guestfs_application2_list * list_applications_windows (guestfs_h *g, struct inspect_fs *fs) { size_t len = strlen (fs->windows_systemroot) + 64; @@ -447,7 +487,7 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs) if (!software_path) return NULL; - struct guestfs_application_list *ret = NULL; + struct guestfs_application2_list *ret = NULL; const char *hivepath[] { "Microsoft", "Windows", "CurrentVersion", "Uninstall" }; const char *hivepath2[] @@ -481,7 +521,7 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs) static void list_applications_windows_from_path (guestfs_h *g, - struct guestfs_application_list *apps, + struct guestfs_application2_list *apps, const char **path, size_t path_len) { struct guestfs_hivex_node_list *children = NULL; @@ -544,7 +584,7 @@ list_applications_windows_from_path (guestfs_h *g, add_application (g, apps, name, display_name, 0, version ? : "", - "", + "", "", install_path ? : "", publisher ? : "", url ? : "", @@ -565,21 +605,22 @@ list_applications_windows_from_path (guestfs_h *g, } static void -add_application (guestfs_h *g, struct guestfs_application_list *apps, +add_application (guestfs_h *g, struct guestfs_application2_list *apps, const char *name, const char *display_name, int32_t epoch, - const char *version, const char *release, + const char *version, const char *release, const char *arch, const char *install_path, const char *publisher, const char *url, const char *description) { apps->len++; apps->val = safe_realloc (g, apps->val, - apps->len * sizeof (struct guestfs_application)); + apps->len * sizeof (struct guestfs_application2)); apps->val[apps->len-1].app_name = safe_strdup (g, name); apps->val[apps->len-1].app_display_name = safe_strdup (g, display_name); apps->val[apps->len-1].app_epoch = epoch; apps->val[apps->len-1].app_version = safe_strdup (g, version); apps->val[apps->len-1].app_release = safe_strdup (g, release); + apps->val[apps->len-1].app_arch = safe_strdup (g, arch); apps->val[apps->len-1].app_install_path = safe_strdup (g, install_path); /* XXX Translated path is not implemented yet. */ apps->val[apps->len-1].app_trans_path = safe_strdup (g, ""); @@ -591,22 +632,27 @@ add_application (guestfs_h *g, struct guestfs_application_list *apps, apps->val[apps->len-1].app_source_package = safe_strdup (g, ""); apps->val[apps->len-1].app_summary = safe_strdup (g, ""); apps->val[apps->len-1].app_description = safe_strdup (g, description); + /* XXX Reserved for future use. */ + apps->val[apps->len-1].app_spare1 = safe_strdup (g, ""); + apps->val[apps->len-1].app_spare2 = safe_strdup (g, ""); + apps->val[apps->len-1].app_spare3 = safe_strdup (g, ""); + apps->val[apps->len-1].app_spare4 = safe_strdup (g, ""); } /* Sort applications by name before returning the list. */ static int compare_applications (const void *vp1, const void *vp2) { - const struct guestfs_application *v1 = vp1; - const struct guestfs_application *v2 = vp2; + const struct guestfs_application2 *v1 = vp1; + const struct guestfs_application2 *v2 = vp2; return strcmp (v1->app_name, v2->app_name); } static void -sort_applications (struct guestfs_application_list *apps) +sort_applications (struct guestfs_application2_list *apps) { if (apps && apps->val) - qsort (apps->val, apps->len, sizeof (struct guestfs_application), + qsort (apps->val, apps->len, sizeof (struct guestfs_application2), compare_applications); } -- 1.7.11.7
John Eckersberg
2012-Nov-01 16:17 UTC
[Libguestfs] [PATCH 2/2] inspect: Use new inspect_list_applications2 API call
--- inspector/virt-inspector.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/inspector/virt-inspector.c b/inspector/virt-inspector.c index 8b06fa7..fc74191 100644 --- a/inspector/virt-inspector.c +++ b/inspector/virt-inspector.c @@ -705,13 +705,13 @@ output_drive_mappings (xmlTextWriterPtr xo, char *root) static void output_applications (xmlTextWriterPtr xo, char *root) { - struct guestfs_application_list *apps; + struct guestfs_application2_list *apps; size_t i; /* This returns an empty list if we simply couldn't determine the * applications, so if it returns NULL then it's a real error. */ - apps = guestfs_inspect_list_applications (g, root); + apps = guestfs_inspect_list_applications2 (g, root); if (apps == NULL) exit (EXIT_FAILURE); @@ -747,6 +747,10 @@ output_applications (xmlTextWriterPtr xo, char *root) XMLERROR (-1, xmlTextWriterWriteElement (xo, BAD_CAST "release", BAD_CAST apps->val[i].app_release)); + if (apps->val[i].app_arch && apps->val[i].app_arch[0]) + XMLERROR (-1, + xmlTextWriterWriteElement (xo, BAD_CAST "arch", + BAD_CAST apps->val[i].app_arch)); if (apps->val[i].app_install_path && apps->val[i].app_install_path[0]) XMLERROR (-1, xmlTextWriterWriteElement (xo, BAD_CAST "install_path", @@ -777,7 +781,7 @@ output_applications (xmlTextWriterPtr xo, char *root) XMLERROR (-1, xmlTextWriterEndElement (xo)); - guestfs_free_application_list (apps); + guestfs_free_application2_list (apps); } static void -- 1.7.11.7
Possibly Parallel Threads
- [PATCH v2 0/3] New inspect_list_applications2 API
- [PATCH 0/2 NOT WORKING] Symbol versioning
- [PATCH for discussion] lib: update inspect_list_applications to return app_arch
- [PATCH v3 0/5] Add symbol versioning.
- [PATCH v2 0/7] Add symbol versioning (now working).