setup: if executing lsb_release doesn't work, fall back to parsing /etc/lsb-release...
authorZooko O'Whielacronx <zooko@zooko.com>
Tue, 23 Sep 2008 16:28:58 +0000 (09:28 -0700)
committerZooko O'Whielacronx <zooko@zooko.com>
Tue, 23 Sep 2008 16:28:58 +0000 (09:28 -0700)
An explanatio of why we do it this way is in the docstring.

src/allmydata/__init__.py

index ea5efb8ee115f3fe76326872625294bd695a2c6b..02ae4fb50725b65180224d7c6af80726a91f8878 100644 (file)
@@ -22,8 +22,11 @@ import _auto_deps
 _auto_deps.require_auto_deps()
 
 import platform, re, subprocess
-_distributor_id = re.compile("(?:Distributor ID)?:?\s*(.*)", re.I)
-_release = re.compile("(?:Release)?:?\s*(.*)", re.I)
+_distributor_id_cmdline_re = re.compile("(?:Distributor ID)?:?\s*(.*)", re.I)
+_release_cmdline_re = re.compile("(?:Release)?:?\s*(.*)", re.I)
+
+_distributor_id_file_re = re.compile("(?:DISTRIB_ID.*=)?\s*(.*)", re.I)
+_release_file_re = re.compile("(?:DISTRIB_RELEASE.*=)?\s*(.*)", re.I)
 
 def get_linux_distro():
     """ Tries to determine the name of the Linux OS distribution name.
@@ -39,8 +42,18 @@ def get_linux_distro():
     If executing "lsb_release" raises no exception, and returns exit code 0, and
     both the "distributor id" and "release" results are non-empty after being
     stripped of whitespace, then return a two-tuple containing the information
-    that lsb_release emitted, as strings.  Else, invoke platform.dist() and
-    return the first two elements of the tuple returned by that function.
+    that lsb_release emitted, as strings.  Why do we execute lsb_release as our
+    first strategy?  Because it is the standard.
+
+    If executing "lsb_release" doesn't work, then try to parse a file named
+    /etc/lsb-release to get the same information.  Why do that?  Because some
+    distributions (at least Debian/Ubuntu) have /etc/lsb-release in the
+    "base-files" package (Priority: required) but /usr/bin/lsb_release in the
+    "lsb-release" package (Priority: important), so it is possible that
+    /etc/lsb-release is there even if /usr/bin/lsb_release isn't.
+
+    If that doesn't work, then invoke platform.dist() and return the first two
+    elements of the tuple returned by that function.
 
     Returns a tuple (distname,version). Distname is what LSB calls a
     "distributor id", e.g. "Ubuntu".  Version is what LSB calls a "release",
@@ -51,20 +64,20 @@ def get_linux_distro():
 
     http://bugs.python.org/issue3937
     """
-    _distname = ""
-    _version = ""
+    _distname = None
+    _version = None
     try:
         p = subprocess.Popen(["lsb_release", "--id"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         rc = p.wait()
         if rc == 0:
-            m = _distributor_id.search(p.stdout.read())
+            m = _distributor_id_cmdline_re.search(p.stdout.read())
             if m:
                 _distname = m.group(1).strip()
 
         p = subprocess.Popen(["lsb_release", "--release"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         rc = p.wait()
         if rc == 0:
-            m = _release.search(p.stdout.read())
+            m = _release_cmdline_re.search(p.stdout.read())
             if m:
                 _version = m.group(1).strip()
     except EnvironmentError:
@@ -72,8 +85,23 @@ def get_linux_distro():
 
     if _distname and _version:
         return (_distname, _version)
-    else:
-        return platform.dist()[:2]
+
+    try:
+        etclsbrel = open("/etc/lsb-release", "rU")
+        for inline in etclsbrel:
+            m = _distributor_id_file_re.search(p.stdout.read())
+            if m:
+                _distname = m.group(1).strip()
+            m = _release_cmdline_re.search(p.stdout.read())
+            if m:
+                _version = m.group(1).strip()
+    except EnvironmentError:
+            pass
+
+    if _distname and _version:
+        return (_distname, _version)
+
+    return platform.dist()[:2]
 
 def get_platform():
     # Our version of platform.platform(), telling us both less and more than the