From: Colin Watson Date: Thu, 26 Jan 2017 14:32:08 +0000 (+0000) Subject: Make lxc-start-ephemeral Python 3.2-compatible X-Git-Tag: lxc-1.0.10~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70cd3b8f65211275363bd2a11254f6d94d389a6f;p=thirdparty%2Flxc.git Make lxc-start-ephemeral Python 3.2-compatible On Ubuntu 12.04 LTS with Python 3.2, `lxc-start-ephemeral` breaks as follows: Traceback (most recent call last): File "/usr/bin/lxc-start-ephemeral", line 371, in attach_as_user File "/usr/lib/python3.2/subprocess.py", line 515, in check_output File "/usr/lib/python3.2/subprocess.py", line 732, in __init__ LookupError: unknown encoding: ANSI_X3.4-1968 This is because `universal_newlines=True` causes `subprocess` to use `io.TextIOWrapper`, and in versions of Python earlier than 3.3 that fetched the preferred encoding using `locale.getpreferredencoding()` rather than `locale.getpreferredencoding(False)`, thereby changing the locale and causing codecs to be reloaded. However, `attach_as_user` runs inside the container and thus can't rely on having access to the same Python standard library on disk. The workaround is to decode by hand instead, avoiding the temporary change of locale. Signed-off-by: Colin Watson --- diff --git a/src/lxc/lxc-start-ephemeral.in b/src/lxc/lxc-start-ephemeral.in index d8240ab0d..9a42ba1e2 100644 --- a/src/lxc/lxc-start-ephemeral.in +++ b/src/lxc/lxc-start-ephemeral.in @@ -28,6 +28,7 @@ import argparse import gettext import lxc +import locale import os import sys import subprocess @@ -337,9 +338,14 @@ if os.path.exists("/proc/self/ns/pid"): if args.user: username = args.user - line = subprocess.check_output( - ["getent", "passwd", username], - universal_newlines=True).rstrip("\n") + # This should really just use universal_newlines=True, but we do + # the decoding by hand instead for compatibility with Python + # 3.2; that used locale.getpreferredencoding() internally rather + # than locale.getpreferredencoding(False), and the former breaks + # here because we can't reload codecs at this point unless the + # container has the same version of Python installed. + line = subprocess.check_output(["getent", "passwd", username]) + line = line.decode(locale.getpreferredencoding(False)).rstrip("\n") _, _, pw_uid, pw_gid, _, pw_dir, _ = line.split(":", 6) pw_uid = int(pw_uid) pw_gid = int(pw_gid)