Changes to bundled distro to be Python-2.6 compatible
* Port bundled distro to use optparse instead of argparse (py2.6) * Use an absolute import to satisfy the current import testing harness * Port from subprocess.check_output to subprocess.Popen.communicate() (py2.6) * Add license location The changes have been proposed upstream here: https://github.com/nir0s/distro/pull/232 Upstream is contemplating a branch where everyone wanting python-2.6 support can collaborate without it becoming part of the regularly supported releases.pull/4420/head
parent
5e1f8a48f3
commit
78a8d09082
|
@ -12,11 +12,9 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# A copy of the Apache License can also be found in the same directory
|
# A local copy of the license can be found in licenses/Apache-License.txt
|
||||||
# as this file (./LICENSE)
|
|
||||||
#
|
#
|
||||||
# Modifications to this code have been made by Ansible Project
|
# Modifications to this code have been made by Ansible Project
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The ``distro`` package (``distro`` stands for Linux Distribution) provides
|
The ``distro`` package (``distro`` stands for Linux Distribution) provides
|
||||||
|
@ -40,7 +38,7 @@ import sys
|
||||||
import json
|
import json
|
||||||
import shlex
|
import shlex
|
||||||
import logging
|
import logging
|
||||||
import argparse
|
import optparse
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,6 +96,56 @@ _DISTRO_RELEASE_IGNORE_BASENAMES = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Python 2.6 does not have subprocess.check_output so replicate it here
|
||||||
|
#
|
||||||
|
def _my_check_output(*popenargs, **kwargs):
|
||||||
|
r"""Run command with arguments and return its output as a byte string.
|
||||||
|
|
||||||
|
If the exit code was non-zero it raises a CalledProcessError. The
|
||||||
|
CalledProcessError object will have the return code in the returncode
|
||||||
|
attribute and output in the output attribute.
|
||||||
|
|
||||||
|
The arguments are the same as for the Popen constructor. Example:
|
||||||
|
|
||||||
|
>>> check_output(["ls", "-l", "/dev/null"])
|
||||||
|
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
|
||||||
|
|
||||||
|
The stdout argument is not allowed as it is used internally.
|
||||||
|
To capture standard error in the result, use stderr=STDOUT.
|
||||||
|
|
||||||
|
>>> check_output(["/bin/sh", "-c",
|
||||||
|
... "ls -l non_existent_file ; exit 0"],
|
||||||
|
... stderr=STDOUT)
|
||||||
|
'ls: non_existent_file: No such file or directory\n'
|
||||||
|
|
||||||
|
This is a backport of Python-2.7's check output to Python-2.6
|
||||||
|
"""
|
||||||
|
if 'stdout' in kwargs:
|
||||||
|
raise ValueError(
|
||||||
|
'stdout argument not allowed, it will be overridden.'
|
||||||
|
)
|
||||||
|
process = subprocess.Popen(
|
||||||
|
stdout=subprocess.PIPE, *popenargs, **kwargs
|
||||||
|
)
|
||||||
|
output, unused_err = process.communicate()
|
||||||
|
retcode = process.poll()
|
||||||
|
if retcode:
|
||||||
|
cmd = kwargs.get("args")
|
||||||
|
if cmd is None:
|
||||||
|
cmd = popenargs[0]
|
||||||
|
# Deviation from Python-2.7: Python-2.6's CalledProcessError does not
|
||||||
|
# have an argument for the stdout so simply omit it.
|
||||||
|
raise subprocess.CalledProcessError(retcode, cmd)
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
_check_output = subprocess.check_output
|
||||||
|
except AttributeError:
|
||||||
|
_check_output = _my_check_output
|
||||||
|
|
||||||
|
|
||||||
def linux_distribution(full_distribution_name=True):
|
def linux_distribution(full_distribution_name=True):
|
||||||
"""
|
"""
|
||||||
Return information about the current OS distribution as a tuple
|
Return information about the current OS distribution as a tuple
|
||||||
|
@ -552,7 +600,7 @@ class cached_property(object):
|
||||||
self._f = f
|
self._f = f
|
||||||
|
|
||||||
def __get__(self, obj, owner):
|
def __get__(self, obj, owner):
|
||||||
assert obj is not None, 'call {} on an instance'.format(self._fname)
|
assert obj is not None, 'call {0} on an instance'.format(self._fname)
|
||||||
ret = obj.__dict__[self._fname] = self._f(obj)
|
ret = obj.__dict__[self._fname] = self._f(obj)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -1001,7 +1049,7 @@ class LinuxDistribution(object):
|
||||||
with open(os.devnull, 'w') as devnull:
|
with open(os.devnull, 'w') as devnull:
|
||||||
try:
|
try:
|
||||||
cmd = ('lsb_release', '-a')
|
cmd = ('lsb_release', '-a')
|
||||||
stdout = subprocess.check_output(cmd, stderr=devnull)
|
stdout = _check_output(cmd, stderr=devnull)
|
||||||
except OSError: # Command not found
|
except OSError: # Command not found
|
||||||
return {}
|
return {}
|
||||||
content = stdout.decode(sys.getfilesystemencoding()).splitlines()
|
content = stdout.decode(sys.getfilesystemencoding()).splitlines()
|
||||||
|
@ -1036,7 +1084,7 @@ class LinuxDistribution(object):
|
||||||
with open(os.devnull, 'w') as devnull:
|
with open(os.devnull, 'w') as devnull:
|
||||||
try:
|
try:
|
||||||
cmd = ('uname', '-rs')
|
cmd = ('uname', '-rs')
|
||||||
stdout = subprocess.check_output(cmd, stderr=devnull)
|
stdout = _check_output(cmd, stderr=devnull)
|
||||||
except OSError:
|
except OSError:
|
||||||
return {}
|
return {}
|
||||||
content = stdout.decode(sys.getfilesystemencoding()).splitlines()
|
content = stdout.decode(sys.getfilesystemencoding()).splitlines()
|
||||||
|
@ -1181,13 +1229,13 @@ def main():
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
logger.addHandler(logging.StreamHandler(sys.stdout))
|
logger.addHandler(logging.StreamHandler(sys.stdout))
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="OS distro info tool")
|
parser = optparse.OptionParser(description="OS distro info tool")
|
||||||
parser.add_argument(
|
parser.add_option(
|
||||||
'--json',
|
'--json',
|
||||||
'-j',
|
'-j',
|
||||||
help="Output in machine readable format",
|
help="Output in machine readable format",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
args = parser.parse_args()
|
args, opts = parser.parse_args()
|
||||||
|
|
||||||
if args.json:
|
if args.json:
|
||||||
logger.info(json.dumps(info(), indent=4, sort_keys=True))
|
logger.info(json.dumps(info(), indent=4, sort_keys=True))
|
||||||
|
|
Loading…
Reference in New Issue