[Libguestfs] [PATCH] Update SuSE Linux detection.

Olaf Hering olaf at aepfle.de
Fri Sep 21 09:00:01 UTC 2012


Update SuSE Linux detection. Up to now everything with a
/etc/SuSE-release file was treated as openSuSE. With this change SLES
based distributions such as "SUSE Linux Enterprise Server", "SUSE
Linux Enterprise Desktop" and "Novell Linux Desktop" will show up as
"sles". The 'opensuse' detection was updated to handle older openSuSE
releases as well as the well known SuSE Linux releases, starting from
6.0. Everything else with a /etc/SuSE-release file will show up as
"suse-based".

Here is a collection of release files:

==> Dist/6.0/etc/SuSE-release <==
SuSE Linux 6.0 (i386)
VERSION = 6.0

==> Dist/6.1/etc/SuSE-release <==
SuSE Linux 6.1 (i386)
VERSION = 6.1

==> Dist/6.2/etc/SuSE-release <==
SuSE Linux 6.2 (i386)
VERSION = 6.2

==> Dist/6.3/etc/SuSE-release <==
SuSE Linux 6.3 (i386)
VERSION = 6.3

==> Dist/6.4/etc/SuSE-release <==
SuSE Linux 6.4 (i386)
VERSION = 6.4

==> Dist/7.0/etc/SuSE-release <==
SuSE Linux 7.0 (i386)
VERSION = 7.0

==> Dist/7.1/etc/SuSE-release <==
SuSE Linux 7.1 (i386)
VERSION = 7.1

==> Dist/7.2/etc/SuSE-release <==
SuSE Linux 7.2 (i386)
VERSION = 7.2

==> Dist/7.3/etc/SuSE-release <==
SuSE Linux 7.3 (i386)
VERSION = 7.3

==> Dist/8.0/etc/SuSE-release <==
SuSE Linux 8.0 (i386)
VERSION = 8.0

==> Dist/8.1/etc/SuSE-release <==
SuSE Linux 8.1 (i386)
VERSION = 8.1

==> Dist/8.2/etc/SuSE-release <==
SuSE Linux 8.2 (x86-64)
VERSION = 8.2

==> Dist/9.0/etc/SuSE-release <==
SuSE Linux 9.0 (x86-64)
VERSION = 9.0

==> Dist/9.1/etc/SuSE-release <==
SuSE Linux 9.1 (x86-64)
VERSION = 9.1

==> Dist/9.2/etc/SuSE-release <==
SuSE Linux 9.2 (x86-64)
VERSION = 9.2

==> Dist/9.3/etc/SuSE-release <==
SuSE Linux 9.3 (x86-64)
VERSION = 9.3

==> Dist/10.0/etc/SuSE-release <==
SUSE LINUX 10.0 (X86-64) OSS
VERSION = 10.0

==> Dist/10.1-remastered/etc/SuSE-release <==
SUSE LINUX 10.1 (X86-64)
VERSION = 10.1

==> Dist/10.1/etc/SuSE-release <==
SUSE Linux 10.1 (X86-64) Beta8
VERSION = 10.1

==> Dist/10.2/etc/SuSE-release <==
openSUSE 10.2 (X86-64)
VERSION = 10.2

==> Dist/10.3/etc/SuSE-release <==
openSUSE 10.3 (X86-64)
VERSION = 10.3

==> Dist/11.0/etc/SuSE-release <==
openSUSE 11.0 (X86-64)
VERSION = 11.0

==> Dist/11.1/etc/SuSE-release <==
openSUSE 11.1 (x86_64)
VERSION = 11.1

==> Dist/11.2/etc/SuSE-release <==
openSUSE 11.2 (x86_64)
VERSION = 11.2

==> Dist/11.3/etc/SuSE-release <==
openSUSE 11.3 (x86_64)
VERSION = 11.3

==> Dist/11.4/etc/SuSE-release <==
openSUSE 11.4 (x86_64)
VERSION = 11.4
CODENAME = Celadon

==> Dist/12.1/etc/SuSE-release <==
openSUSE 12.1 (x86_64)
VERSION = 12.1
CODENAME = Asparagus

==> Dist/12.2/etc/SuSE-release <==
openSUSE 12.2 (x86_64)
VERSION = 12.2
CODENAME = Mantis

==> Dist/sles8/etc/SuSE-release <==
SuSE SLES-8 (AMD64)
VERSION = 8.1

==> Dist/sles9/etc/SuSE-release <==
SUSE LINUX Enterprise Server 9 (x86_64)
VERSION = 9

==> Dist/sles9sp2/etc/SuSE-release <==
SUSE LINUX Enterprise Server 9 (x86_64)
VERSION = 9
PATCHLEVEL = 2

==> Dist/sles9sp3/etc/SuSE-release <==
SUSE LINUX Enterprise Server 9 (x86_64)
VERSION = 9
PATCHLEVEL = 3

==> Dist/sles9sp4/etc/SuSE-release <==
SUSE LINUX Enterprise Server 9 (x86_64)
VERSION = 9
PATCHLEVEL = 4
==> Dist/sled10/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 10 (x86_64)
VERSION = 10

==> Dist/sled10sp1/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 10 (x86_64)
VERSION = 10
PATCHLEVEL = 1

==> Dist/sled10sp2/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 10 (x86_64)
VERSION = 10
PATCHLEVEL = 2

==> Dist/sled10sp3/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 10 (x86_64)
VERSION = 10
PATCHLEVEL = 3

==> Dist/sled10sp4/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 10 (x86_64)
VERSION = 10
PATCHLEVEL = 4

==> Dist/sled11/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 11 (x86_64)
VERSION = 11
PATCHLEVEL = 0

==> Dist/sled11sp1/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 11 (x86_64)
VERSION = 11
PATCHLEVEL = 1

==> Dist/sled11sp2/etc/SuSE-release <==
SUSE Linux Enterprise Desktop 11 (x86_64)
VERSION = 11
PATCHLEVEL = 2

==> Dist/sles10/etc/SuSE-release <==
SUSE Linux Enterprise Server 10 (x86_64)
VERSION = 10

==> Dist/sles10sp1/etc/SuSE-release <==
SUSE Linux Enterprise Server 10 (x86_64)
VERSION = 10
PATCHLEVEL = 1

==> Dist/sles10sp2/etc/SuSE-release <==
SUSE Linux Enterprise Server 10 (x86_64)
VERSION = 10
PATCHLEVEL = 2

==> Dist/sles10sp3/etc/SuSE-release <==
SUSE Linux Enterprise Server 10 (x86_64)
VERSION = 10
PATCHLEVEL = 3

==> Dist/sles10sp4/etc/SuSE-release <==
SUSE Linux Enterprise Server 10 (x86_64)
VERSION = 10
PATCHLEVEL = 4

==> Dist/sles11/etc/SuSE-release <==
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 0

==> Dist/sles11sp1/etc/SuSE-release <==
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 1

==> Dist/sles11sp2/etc/SuSE-release <==
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 2

Signed-off-by: Olaf Hering <olaf at aepfle.de>
---
 generator/actions.ml   |   8 ++++
 src/guestfs-internal.h |   2 +
 src/inspect-fs-unix.c  | 100 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/inspect-fs.c       |   4 ++
 src/inspect-icon.c     |   2 +
 src/inspect.c          |   2 +
 6 files changed, 114 insertions(+), 4 deletions(-)

diff --git a/generator/actions.ml b/generator/actions.ml
index a17fed0..438b316 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -1000,6 +1000,14 @@ Scientific Linux.
 
 Slackware.
 
+=item \"sles\"
+
+SuSE Linux Enterprise Server or Desktop.
+
+=item \"suse-based\"
+
+Some openSuSE-derived distro.
+
 =item \"ttylinux\"
 
 ttylinux.
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 8f2e26d..22f1623 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -346,6 +346,8 @@ enum inspect_os_distro {
   OS_DISTRO_BUILDROOT,
   OS_DISTRO_CIRROS,
   OS_DISTRO_FREEDOS,
+  OS_DISTRO_SUSE_BASED,
+  OS_DISTRO_SLES,
 };
 
 enum inspect_os_package_format {
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index b8141d5..91b8516 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -67,6 +67,12 @@ static pcre *re_mdN;
 static pcre *re_freebsd;
 static pcre *re_diskbyid;
 static pcre *re_netbsd;
+static pcre *re_opensuse;
+static pcre *re_sles;
+static pcre *re_nld;
+static pcre *re_opensuse_version;
+static pcre *re_sles_version;
+static pcre *re_sles_patchlevel;
 
 static void compile_regexps (void) __attribute__((constructor));
 static void free_regexps (void) __attribute__((destructor));
@@ -112,6 +118,12 @@ compile_regexps (void)
   COMPILE (re_freebsd, "^/dev/ad(\\d+)s(\\d+)([a-z])$", 0);
   COMPILE (re_diskbyid, "^/dev/disk/by-id/.*-part(\\d+)$", 0);
   COMPILE (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0);
+  COMPILE (re_opensuse, "^(openSUSE|SuSE Linux|SUSE LINUX) ", 0);
+  COMPILE (re_sles, "^SUSE (Linux|LINUX) Enterprise ", 0);
+  COMPILE (re_nld, "^Novell Linux Desktop ", 0);
+  COMPILE (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0);
+  COMPILE (re_sles_version, "^VERSION = (\\d+)", 0);
+  COMPILE (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0);
 }
 
 static void
@@ -134,6 +146,12 @@ free_regexps (void)
   pcre_free (re_freebsd);
   pcre_free (re_diskbyid);
   pcre_free (re_netbsd);
+  pcre_free (re_opensuse);
+  pcre_free (re_sles);
+  pcre_free (re_nld);
+  pcre_free (re_opensuse_version);
+  pcre_free (re_sles_version);
+  pcre_free (re_sles_patchlevel);
 }
 
 static void check_architecture (guestfs_h *g, struct inspect_fs *fs);
@@ -301,6 +319,82 @@ parse_lsb_release (guestfs_h *g, struct inspect_fs *fs)
   return r ? 1 : 0;
 }
 
+static int
+parse_suse_release (guestfs_h *g, struct inspect_fs *fs, const char *filename)
+{
+  int64_t size;
+  char *major, *minor;
+  char **lines;
+  int r = -1;
+
+  /* Don't trust guestfs_head_n not to break with very large files.
+   * Check the file size is something reasonable first.
+   */
+  size = guestfs_filesize (g, filename);
+  if (size == -1)
+    /* guestfs_filesize failed and has already set error in handle */
+    return -1;
+  if (size > MAX_SMALL_FILE_SIZE) {
+    error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"),
+           filename, size);
+    return -1;
+  }
+
+  lines = guestfs_head_n (g, 10, filename);
+  if (lines == NULL)
+    return -1;
+
+  /* First line is dist release name */
+  fs->product_name = safe_strdup (g, lines[0]);
+  if (fs->product_name == NULL)
+    goto out;
+
+  /* Match SLES first because openSuSE regex overlaps some SLES release strings */
+  if (match (g, fs->product_name, re_sles) || match (g, fs->product_name, re_nld)) {
+    fs->distro = OS_DISTRO_SLES;
+
+    /* Second line contains version string */
+    if (lines[1] == NULL)
+      goto out;
+    major = match1 (g, lines[1], re_sles_version);
+    fs->major_version = guestfs___parse_unsigned_int (g, major);
+    free (major);
+    if (fs->major_version == -1)
+      goto out;
+
+    /* Third line contains service pack string */
+    if (lines[2] == NULL)
+      goto out;
+    minor = match1 (g, lines[2], re_sles_patchlevel);
+    fs->minor_version = guestfs___parse_unsigned_int (g, minor);
+    free (minor);
+    if (fs->minor_version == -1)
+      goto out;
+  }
+  else if (match (g, fs->product_name, re_opensuse)) {
+    fs->distro = OS_DISTRO_OPENSUSE;
+
+    /* Second line contains version string */
+    if (lines[1] == NULL)
+      goto out;
+    if (match2 (g, lines[1], re_opensuse_version, &major, &minor)) {
+      fs->major_version = guestfs___parse_unsigned_int (g, major);
+      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
+      free (major);
+      free (minor);
+      if (fs->major_version == -1 || fs->minor_version == -1)
+        goto out;
+    }
+  }
+
+  r = 0;
+
+out:
+  guestfs___free_string_list (lines);
+
+  return r;
+}
+
 /* The currently mounted device is known to be a Linux root.  Try to
  * determine from this the distro, version, etc.  Also parse
  * /etc/fstab to determine the arrangement of mountpoints and
@@ -464,13 +558,11 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs)
       return -1;
   }
   else if (guestfs_exists (g, "/etc/SuSE-release") > 0) {
-    fs->distro = OS_DISTRO_OPENSUSE;
+    fs->distro = OS_DISTRO_SUSE_BASED;
 
-    if (parse_release_file (g, fs, "/etc/SuSE-release") == -1)
+    if (parse_suse_release (g, fs, "/etc/SuSE-release") == -1)
       return -1;
 
-    if (guestfs___parse_major_minor (g, fs) == -1)
-      return -1;
   }
   /* Buildroot (http://buildroot.net) is an embedded Linux distro
    * toolkit.  It is used by specific distros such as Cirros.
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index 7354029..2dbafb5 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -410,7 +410,9 @@ check_package_format (guestfs_h *g, struct inspect_fs *fs)
   case OS_DISTRO_RHEL:
   case OS_DISTRO_MAGEIA:
   case OS_DISTRO_MANDRIVA:
+  case OS_DISTRO_SUSE_BASED:
   case OS_DISTRO_OPENSUSE:
+  case OS_DISTRO_SLES:
   case OS_DISTRO_CENTOS:
   case OS_DISTRO_SCIENTIFIC_LINUX:
     fs->package_format = OS_PACKAGE_FORMAT_RPM;
@@ -484,7 +486,9 @@ check_package_management (guestfs_h *g, struct inspect_fs *fs)
     fs->package_management = OS_PACKAGE_MANAGEMENT_URPMI;
     break;
 
+  case OS_DISTRO_SUSE_BASED:
   case OS_DISTRO_OPENSUSE:
+  case OS_DISTRO_SLES:
     fs->package_management = OS_PACKAGE_MANAGEMENT_ZYPPER;
     break;
 
diff --git a/src/inspect-icon.c b/src/inspect-icon.c
index 19acfb9..531ba61 100644
--- a/src/inspect-icon.c
+++ b/src/inspect-icon.c
@@ -152,7 +152,9 @@ guestfs__inspect_get_icon (guestfs_h *g, const char *root, size_t *size_r,
       r = icon_mageia (g, fs, &size);
       break;
 
+    case OS_DISTRO_SUSE_BASED:
     case OS_DISTRO_OPENSUSE:
+    case OS_DISTRO_SLES:
       r = icon_opensuse (g, fs, &size);
       break;
 
diff --git a/src/inspect.c b/src/inspect.c
index 5dd9266..f16aea1 100644
--- a/src/inspect.c
+++ b/src/inspect.c
@@ -232,6 +232,8 @@ guestfs__inspect_get_distro (guestfs_h *g, const char *root)
   case OS_DISTRO_RHEL: ret = safe_strdup (g, "rhel"); break;
   case OS_DISTRO_SCIENTIFIC_LINUX: ret = safe_strdup (g, "scientificlinux"); break;
   case OS_DISTRO_SLACKWARE: ret = safe_strdup (g, "slackware"); break;
+  case OS_DISTRO_SLES: ret = safe_strdup (g, "sles"); break;
+  case OS_DISTRO_SUSE_BASED: ret = safe_strdup (g, "suse-based"); break;
   case OS_DISTRO_TTYLINUX: ret = safe_strdup (g, "ttylinux"); break;
   case OS_DISTRO_WINDOWS: ret = safe_strdup (g, "windows"); break;
   case OS_DISTRO_UBUNTU: ret = safe_strdup (g, "ubuntu"); break;
-- 
1.7.12




More information about the Libguestfs mailing list