New APIs: inspect-get-package-format, inspect-get-package-management.

This APIs reimplement some parts of virt-inspector in C.
This commit is contained in:
Richard Jones
2010-11-12 12:29:14 +00:00
committed by Richard W.M. Jones
parent 6ab5783721
commit 3fd2b9d0b6
4 changed files with 228 additions and 49 deletions

View File

@@ -1119,6 +1119,52 @@ The optional parameters are passed directly through to
C<guestfs_add_drive_opts>.");
*)
("inspect_get_package_format", (RString "packageformat", [Device "root"], []), -1, [],
[],
"get package format used by the operating system",
"\
This function should only be called with a root device string
as returned by C<guestfs_inspect_os>.
This function and C<guestfs_inspect_get_package_management> return
the package format and package management tool used by the
inspected operating system. For example for Fedora these
functions would return C<rpm> (package format) and
C<yum> (package management).
This returns the string C<unknown> if we could not determine the
package format I<or> if the operating system does not have
a real packaging system (eg. Windows).
Possible strings include: C<rpm>, C<deb>, C<ebuild>, C<pisi>, C<pacman>.
Future versions of libguestfs may return other strings.
Please read L<guestfs(3)/INSPECTION> for more details.");
("inspect_get_package_management", (RString "packagemanagement", [Device "root"], []), -1, [],
[],
"get package management tool used by the operating system",
"\
This function should only be called with a root device string
as returned by C<guestfs_inspect_os>.
C<guestfs_inspect_get_package_format> and this function return
the package format and package management tool used by the
inspected operating system. For example for Fedora these
functions would return C<rpm> (package format) and
C<yum> (package management).
This returns the string C<unknown> if we could not determine the
package management tool I<or> if the operating system does not have
a real packaging system (eg. Windows).
Possible strings include: C<yum>, C<up2date>,
C<apt> (for all Debian derivatives),
C<portage>, C<pisi>, C<pacman>.
Future versions of libguestfs may return other strings.
Please read L<guestfs(3)/INSPECTION> for more details.");
]
(* daemon_functions are any functions which cause some action

View File

@@ -200,17 +200,17 @@ foreach $root (@roots) {
# Basic OS fields.
$xml->dataElement (root => canonicalize ($root));
my ($s, $distro, $major_version);
my $s;
$s = $g->inspect_get_type ($root);
$xml->dataElement (name => $s) if $s ne "unknown";
$s = $g->inspect_get_arch ($root);
$xml->dataElement (arch => $s) if $s ne "unknown";
$distro = $g->inspect_get_distro ($root);
$xml->dataElement (distro => $distro) if $distro ne "unknown";
$s = $g->inspect_get_distro ($root);
$xml->dataElement (distro => $s) if $s ne "unknown";
$s = $g->inspect_get_product_name ($root);
$xml->dataElement (product_name => $s) if $s ne "unknown";
$major_version = $g->inspect_get_major_version ($root);
$xml->dataElement (major_version => $major_version);
$s = $g->inspect_get_major_version ($root);
$xml->dataElement (major_version => $s);
$s = $g->inspect_get_minor_version ($root);
$xml->dataElement (minor_version => $s);
@@ -226,7 +226,7 @@ foreach $root (@roots) {
output_filesystems ($root);
# Package format / management and applications.
output_applications ($root, $distro, $major_version);
output_applications ($root);
$xml->endTag("operatingsystem");
@@ -370,58 +370,24 @@ sub output_applications
{
local $_;
my $root = shift;
my $distro = shift;
my $major_version = shift;
# Based on the distro, take a guess at the package format
# and package management.
my ($package_format, $package_management);
if (defined $distro) {
if ($distro eq "archlinux") {
$package_format = "pacman";
$package_management = "pacman";
}
elsif ($distro eq "debian" || $distro eq "ubuntu") {
$package_format = "deb";
$package_management = "apt";
}
elsif ($distro eq "fedora" || $distro eq "meego") {
$package_format = "rpm";
$package_management = "yum";
}
elsif ($distro eq "gentoo") {
$package_format = "ebuild";
$package_management = "portage";
}
elsif ($distro eq "pardus") {
$package_format = "pisi";
$package_management = "pisi";
}
elsif ($distro =~ /redhat/ || $distro =~ /rhel/) {
if ($major_version >= 5) {
$package_format = "rpm";
$package_management = "yum";
} else {
$package_format = "rpm";
$package_management = "up2date";
}
}
# else unknown.
}
$package_format = $g->inspect_get_package_format ($root);
$package_management = $g->inspect_get_package_management ($root);
$xml->dataElement (package_format => $package_format)
if defined $package_format;
if $package_format ne "unknown";
$xml->dataElement (package_management => $package_management)
if defined $package_management;
if $package_management ne "unknown";
# Do we know how to get a list of applications?
if (defined $package_format) {
if ($package_format eq "rpm") {
output_applications_rpm ($root);
}
elsif ($package_format eq "deb") {
output_applications_deb ($root);
}
if ($package_format eq "rpm") {
output_applications_rpm ($root);
}
elsif ($package_format eq "deb") {
output_applications_deb ($root);
}
}

View File

@@ -181,6 +181,25 @@ enum inspect_os_distro {
OS_DISTRO_MEEGO,
};
enum inspect_os_package_format {
OS_PACKAGE_FORMAT_UNKNOWN = 0,
OS_PACKAGE_FORMAT_RPM,
OS_PACKAGE_FORMAT_DEB,
OS_PACKAGE_FORMAT_PACMAN,
OS_PACKAGE_FORMAT_EBUILD,
OS_PACKAGE_FORMAT_PISI
};
enum inspect_os_package_management {
OS_PACKAGE_MANAGEMENT_UNKNOWN = 0,
OS_PACKAGE_MANAGEMENT_YUM,
OS_PACKAGE_MANAGEMENT_UP2DATE,
OS_PACKAGE_MANAGEMENT_APT,
OS_PACKAGE_MANAGEMENT_PACMAN,
OS_PACKAGE_MANAGEMENT_PORTAGE,
OS_PACKAGE_MANAGEMENT_PISI,
};
struct inspect_fs {
int is_root;
char *device;
@@ -189,6 +208,8 @@ struct inspect_fs {
enum inspect_fs_content content;
enum inspect_os_type type;
enum inspect_os_distro distro;
enum inspect_os_package_format package_format;
enum inspect_os_package_management package_management;
char *product_name;
int major_version;
int minor_version;

View File

@@ -197,6 +197,8 @@ static int parse_unsigned_int (guestfs_h *g, const char *str);
static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
const char *spec, const char *mp);
static char *resolve_fstab_device (guestfs_h *g, const char *spec);
static void check_package_format (guestfs_h *g, struct inspect_fs *fs);
static void check_package_management (guestfs_h *g, struct inspect_fs *fs);
static int
check_for_filesystem_on (guestfs_h *g, const char *device)
@@ -516,6 +518,10 @@ check_linux_root (guestfs_h *g, struct inspect_fs *fs)
skip_release_checks:;
/* If distro test above was successful, work out the package format. */
check_package_format (g, fs);
check_package_management (g, fs);
/* Determine the architecture. */
const char *binaries[] =
{ "/bin/bash", "/bin/ls", "/bin/echo", "/bin/rm", "/bin/sh" };
@@ -776,6 +782,9 @@ check_windows_root (guestfs_h *g, struct inspect_fs *fs)
if (check_windows_registry (g, fs) == -1)
return -1;
check_package_format (g, fs);
check_package_management (g, fs);
return 0;
}
@@ -972,6 +981,84 @@ parse_unsigned_int (guestfs_h *g, const char *str)
return ret;
}
/* At the moment, package format and package management is just a
* simple function of the distro and major_version fields, so these
* can never return an error. We might be cleverer in future.
*/
static void
check_package_format (guestfs_h *g, struct inspect_fs *fs)
{
switch (fs->distro) {
case OS_DISTRO_FEDORA:
case OS_DISTRO_MEEGO:
case OS_DISTRO_REDHAT_BASED:
case OS_DISTRO_RHEL:
fs->package_format = OS_PACKAGE_FORMAT_RPM;
break;
case OS_DISTRO_DEBIAN:
case OS_DISTRO_UBUNTU:
fs->package_format = OS_PACKAGE_FORMAT_DEB;
break;
case OS_DISTRO_ARCHLINUX:
fs->package_format = OS_PACKAGE_FORMAT_PACMAN;
break;
case OS_DISTRO_GENTOO:
fs->package_format = OS_PACKAGE_FORMAT_EBUILD;
break;
case OS_DISTRO_PARDUS:
fs->package_format = OS_PACKAGE_FORMAT_PISI;
break;
case OS_DISTRO_WINDOWS:
case OS_DISTRO_UNKNOWN:
default:
fs->package_format = OS_PACKAGE_FORMAT_UNKNOWN;
break;
}
}
static void
check_package_management (guestfs_h *g, struct inspect_fs *fs)
{
switch (fs->distro) {
case OS_DISTRO_FEDORA:
case OS_DISTRO_MEEGO:
fs->package_management = OS_PACKAGE_MANAGEMENT_YUM;
break;
case OS_DISTRO_REDHAT_BASED:
case OS_DISTRO_RHEL:
if (fs->major_version >= 5)
fs->package_management = OS_PACKAGE_MANAGEMENT_YUM;
else
fs->package_management = OS_PACKAGE_MANAGEMENT_UP2DATE;
break;
case OS_DISTRO_DEBIAN:
case OS_DISTRO_UBUNTU:
fs->package_management = OS_PACKAGE_MANAGEMENT_APT;
break;
case OS_DISTRO_ARCHLINUX:
fs->package_management = OS_PACKAGE_MANAGEMENT_PACMAN;
break;
case OS_DISTRO_GENTOO:
fs->package_management = OS_PACKAGE_MANAGEMENT_PORTAGE;
break;
case OS_DISTRO_PARDUS:
fs->package_management = OS_PACKAGE_MANAGEMENT_PISI;
break;
case OS_DISTRO_WINDOWS:
case OS_DISTRO_UNKNOWN:
default:
fs->package_management = OS_PACKAGE_MANAGEMENT_UNKNOWN;
break;
}
}
static struct inspect_fs *
search_for_root (guestfs_h *g, const char *root)
{
@@ -1194,6 +1281,53 @@ guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
return ret;
}
char *
guestfs__inspect_get_package_format (guestfs_h *g, const char *root)
{
struct inspect_fs *fs = search_for_root (g, root);
if (!fs)
return NULL;
char *ret;
switch (fs->package_format) {
case OS_PACKAGE_FORMAT_RPM: ret = safe_strdup (g, "rpm"); break;
case OS_PACKAGE_FORMAT_DEB: ret = safe_strdup (g, "deb"); break;
case OS_PACKAGE_FORMAT_PACMAN: ret = safe_strdup (g, "pacman"); break;
case OS_PACKAGE_FORMAT_EBUILD: ret = safe_strdup (g, "ebuild"); break;
case OS_PACKAGE_FORMAT_PISI: ret = safe_strdup (g, "pisi"); break;
case OS_PACKAGE_FORMAT_UNKNOWN:
default:
ret = safe_strdup (g, "unknown");
break;
}
return ret;
}
char *
guestfs__inspect_get_package_management (guestfs_h *g, const char *root)
{
struct inspect_fs *fs = search_for_root (g, root);
if (!fs)
return NULL;
char *ret;
switch (fs->package_management) {
case OS_PACKAGE_MANAGEMENT_YUM: ret = safe_strdup (g, "yum"); break;
case OS_PACKAGE_MANAGEMENT_UP2DATE: ret = safe_strdup (g, "up2date"); break;
case OS_PACKAGE_MANAGEMENT_APT: ret = safe_strdup (g, "apt"); break;
case OS_PACKAGE_MANAGEMENT_PACMAN: ret = safe_strdup (g, "pacman"); break;
case OS_PACKAGE_MANAGEMENT_PORTAGE: ret = safe_strdup (g, "portage"); break;
case OS_PACKAGE_MANAGEMENT_PISI: ret = safe_strdup (g, "pisi"); break;
case OS_PACKAGE_MANAGEMENT_UNKNOWN:
default:
ret = safe_strdup (g, "unknown");
break;
}
return ret;
}
#else /* no PCRE or hivex at compile time */
/* XXX These functions should be in an optgroup. */
@@ -1268,6 +1402,18 @@ guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
NOT_IMPL(NULL);
}
char *
guestfs__inspect_get_package_format (guestfs_h *g, const char *root)
{
NOT_IMPL(NULL);
}
char *
guestfs__inspect_get_package_management (guestfs_h *g, const char *root)
{
NOT_IMPL(NULL);
}
#endif /* no PCRE or hivex at compile time */
void