From 7f16c346bbeba2f2fe3c31ccb85158178a284d84 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 27 Jun 2011 15:27:46 +0100 Subject: [PATCH] New API: inspect-get-icon returns the guest icon. This API returns the guest's favicon if found, else an icon representing the guest operating system. Currently supported by this patch: Fedora, RHEL and derivatives, Debian (but not Ubuntu), Windows XP, Windows 7. This also updates virt-inspector to include an element containing the icon in base64 encoding. --- TODO | 7 - generator/generator_actions.ml | 64 ++++++ inspector/virt-inspector.c | 32 ++- inspector/virt-inspector.rng | 6 +- po/POTFILES.in | 1 + src/Makefile.am | 1 + src/guestfs-internal.h | 3 + src/inspect_icon.c | 470 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 569 insertions(+), 15 deletions(-) create mode 100644 src/inspect_icon.c diff --git a/TODO b/TODO index c5eab92..3a0a6b0 100644 --- a/TODO +++ b/TODO @@ -441,13 +441,6 @@ More inspection features - last user who logged in - lastlog, last, who -Get the guest icon ------------------- - -- For Linux guests, use /etc/favicon.png if available, else get it in - a distro-specific manner. -- For Windows guests, parse it out of c:\windows\explorer.exe - Integrate virt-inspector with CMDBs ----------------------------------- diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index fa2ff08..d741dfb 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -1462,6 +1462,70 @@ Please read L for more details. See also C, C."); + ("inspect_get_icon", (RBufferOut "icon", [Device "root"], [Bool "favicon"; Bool "highquality"]), -1, [], + [], + "get the icon corresponding to this operating system", + "\ +This function returns an icon corresponding to the inspected +operating system. The icon is returned as a buffer containing a +PNG image (re-encoded to PNG if necessary). + +If it was not possible to get an icon this function returns a +zero-length (non-NULL) buffer. I. + +Libguestfs will start by looking for a file called +C or C +and if it has the correct format, the contents of this file will +be returned. You can disable favicons by passing the +optional C boolean as false (default is true). + +If finding the favicon fails, then we look in other places in the +guest for a suitable icon. + +If the optional C boolean is true then +only high quality icons are returned, which means only icons of +high resolution with an alpha channel. The default (false) is +to return any icon we can, even if it is of substandard quality. + +Notes: + +=over 4 + +=item * + +Unlike most other inspection API calls, the guest's disks must be +mounted up before you call this, since it needs to read information +from the guest filesystem during the call. + +=item * + +B The icon data comes from the untrusted guest, +and should be treated with caution. PNG files have been +known to contain exploits. Ensure that libpng (or other relevant +libraries) are fully up to date before trying to process or +display the icon. + +=item * + +The PNG image returned can be any size. It might not be square. +Libguestfs tries to return the largest, highest quality +icon available. The application must scale the icon to the +required size. + +=item * + +Extracting icons from Windows guests requires the external +C program from the C package, and +several programs (C, C, C) +from the C package. These must be installed separately. + +=item * + +Operating system icons are usually trademarks. Seek legal +advice before using trademarks in applications. + +=back"); + ] (* daemon_functions are any functions which cause some action diff --git a/inspector/virt-inspector.c b/inspector/virt-inspector.c index 607e5ae..4afce0e 100644 --- a/inspector/virt-inspector.c +++ b/inspector/virt-inspector.c @@ -340,6 +340,7 @@ output_root (xmlTextWriterPtr xo, char *root) int i, r; char buf[32]; char canonical_root[strlen (root) + 1]; + size_t size; XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "operatingsystem")); @@ -471,8 +472,32 @@ output_root (xmlTextWriterPtr xo, char *root) output_drive_mappings (xo, root); + /* We need to mount everything up in order to read out the list of + * applications and the icon, ie. everything below this point. + */ + inspect_mount_root (root); + output_applications (xo, root); + /* Don't return favicon. XXX Should we? */ + str = guestfs_inspect_get_icon (g, root, &size, + GUESTFS_INSPECT_GET_ICON_FAVICON, 0, + -1); + if (!str) exit (EXIT_FAILURE); + if (size > 0) { + XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "icon")); + XMLERROR (-1, xmlTextWriterWriteBase64 (xo, str, 0, size)); + XMLERROR (-1, xmlTextWriterEndElement (xo)); + } + /* Note we must free (str) even if size == 0, because that indicates + * there was no icon. + */ + free (str); + + /* Unmount (see inspect_mount_root above). */ + if (guestfs_umount_all (g) == -1) + exit (EXIT_FAILURE); + XMLERROR (-1, xmlTextWriterEndElement (xo)); } @@ -652,19 +677,12 @@ output_applications (xmlTextWriterPtr xo, char *root) struct guestfs_application_list *apps; size_t i; - /* We need to mount everything up in order to read out the list of - * applications. - */ - inspect_mount_root (root); - /* 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); if (apps == NULL) exit (EXIT_FAILURE); - if (guestfs_umount_all (g) == -1) - exit (EXIT_FAILURE); XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "applications")); diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng index 480467e..4fd208a 100644 --- a/inspector/virt-inspector.rng +++ b/inspector/virt-inspector.rng @@ -1,4 +1,6 @@ - +