From 5075c127250c5ad0b9eca6150b282b9df8003100 Mon Sep 17 00:00:00 2001
From: Zooko O'Whielacronx <zooko@zooko.com>
Date: Mon, 22 Sep 2008 16:53:54 -0700
Subject: [PATCH] setup: simplify the implementation of
 allmydata.get_package_versions() and add "platform" which is a human-oriented
 summary of the underlying operating system and machine

---
 src/allmydata/__init__.py | 78 +++++++++++++++++++++++++++++++--------
 1 file changed, 63 insertions(+), 15 deletions(-)

diff --git a/src/allmydata/__init__.py b/src/allmydata/__init__.py
index 85e3dd15..45881b50 100644
--- a/src/allmydata/__init__.py
+++ b/src/allmydata/__init__.py
@@ -1,4 +1,3 @@
-
 """
 Decentralized storage grid.
 
@@ -22,38 +21,87 @@ del hush_pyflakes
 import _auto_deps
 _auto_deps.require_auto_deps()
 
-def get_package_versions():
-    import OpenSSL, allmydata, foolscap, nevow, pycryptopp, simplejson, twisted, zfec, sys
+import platform, re, subprocess
+_distributor_id = re.compile("(?:Distributor ID)?:?\s*(.*)", re.I)
+_release = re.compile("(?:Release)?:?\s*(.*)", re.I)
 
-    try:
-        pyver = '.'.join([str(c) for c in sys.version_info])
-    except:
-        # This will probably never happen, but if it does:
-        pyver = sys.version
+def get_linux_distro():
+    """ Tries to determine the name of the Linux OS distribution name.
+
+    The function tries to execute "lsb_release", as standardized in 2001:
+
+    http://refspecs.freestandards.org/LSB_1.0.0/gLSB/lsbrelease.html
+
+    The current version of the standard is here:
+
+    http://refspecs.freestandards.org/LSB_3.2.0/LSB-Core-generic/LSB-Core-generic/lsbrelease.html
+
+    If executing "lsb_release" raises no exception, and returns exit code 0,
+    then return a two-tuple containing the information that lsb_release emitted
+    as strings.
 
-    setuptools_version = "unavailable"
+    Returns a tuple (distname,version). Distname is what LSB calls a
+    "distributor id", e.g. "Ubuntu".  Version is what LSB calls a "release",
+    e.g. "8.04".
+
+    A version of this has been submitted to python as a patch for the standard
+    library module "platform":
+
+    http://bugs.python.org/issue3937
+    """
+    _distname = ""
+    _version = ""
     try:
-        import setuptools
-        setuptools_version = setuptools.__version__
-    except ImportError:
+        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())
+            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())
+            if m:
+                _version = m.group(1).strip()
+    except EnvironmentError:
         pass
+
+    return (_distname, _version)
+
+def get_platform():
+    # Our version of platform.platform(), telling us both less and more than the
+    # Python Standard Library's version does.
+    # We omit details such as the Linux kernel version number, but we add a
+    # more detailed and correct rendition of the Linux distribution and
+    # distribution-version.
+    if "linux" in platform.system().lower():
+        return platform.system()+"-"+"_".join(get_linux_distro())+"-"+platform.machine()+"-"+"_".join([x for x in platform.architecture() if x])
+    else:
+        return platform.platform()
+
+def get_package_versions():
+    import OpenSSL, allmydata, foolscap, nevow, platform, pycryptopp, setuptools, simplejson, twisted, zfec
+
     return {
         'pyopenssl': OpenSSL.__version__,
         'allmydata': allmydata.__version__,
         'foolscap': foolscap.__version__,
         'nevow': nevow.__version__,
         'pycryptopp': pycryptopp.__version__,
-        'setuptools': setuptools_version,
+        'setuptools': setuptools.__version__,
         'simplejson': simplejson.__version__,
         'twisted': twisted.__version__,
         'zfec': zfec.__version__,
-        'python': pyver,
+        'python': platform.python_version(),
+        'platform': get_platform()
         }
 
 def get_package_versions_string():
     versions = get_package_versions()
     res = []
-    for p in ["allmydata", "foolscap", "pycryptopp", "zfec", "twisted", "nevow", "python"]:
+    for p in ["allmydata", "foolscap", "pycryptopp", "zfec", "twisted", "nevow", "python", "platform"]:
         if versions.has_key(p):
             res.append(str(p) + ": " + str(versions[p]))
             del versions[p]
-- 
2.45.2