Redirecting stderr to stdout is suseptible to breakage due to warning output to stderr
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Charm Helpers |
Triaged
|
High
|
Unassigned |
Bug Description
As LP Bug#1868322 [0] showed many charm helpers are susceptible to breakage when warning messages are sent to stderr.
The pattern of redirecting stderr to stdout for subprocess, stderr=
def network_
...
cmd = ['network-get', '--primary-
try:
response = subprocess.
cmd,
except CalledProcessError as e:
if 'no network config found for binding' in e.output.
raise NoNetworkBindin
...
Per the subprocess documentation [1] we should use e.stderr for exception handling rather than redirecting stderr to stdout:
try:
response = subprocess.
except CalledProcessError as e:
if 'no network config found for binding' in e.stderr.
raise NoNetworkBindin
[0] https:/
[1] https:/
Changed in charm-helpers: | |
status: | New → Triaged |
importance: | Undecided → High |
A quick and dirty grep of the charm-helpers code reveals 25ish sites that need looking at in the charm-helpers code to make charm-helpers less brittle to this issue:
charmhelpers/ payload/ execd.py: 50:def execd_run(command, execd_dir=None, die_on_error=True, stderr= subprocess. STDOUT) : payload/ execd.py: 54: subprocess. check_output( submodule_ path, stderr=stderr, core/host. py:294: cmd, stderr= subprocess. STDOUT) .decode( 'UTF-8' ) core/host. py:502: return subprocess. check_output( cmd, stderr= subprocess. STDOUT) .decode( 'UTF-8' ).strip( ) core/host_ factory/ ubuntu. py:48: stderr= subprocess. STDOUT) .decode( 'UTF-8' ) core/hookenv. py:1340: stderr= subprocess. STDOUT) .decode( 'UTF-8' ).strip( ) core/hookenv. py:1370: stderr= subprocess. STDOUT) .decode( 'UTF-8' ).strip( ) fetch/bzrurl. py:58: check_output(cmd, stderr=STDOUT) fetch/giturl. py:53: check_output(cmd, stderr=STDOUT) fetch/ubuntu. py:433: stderr= subprocess. PIPE, fetch/ubuntu. py:492: stderr= subprocess. PIPE, fetch/ubuntu_ apt_pkg. py:111: stderr= subprocess. STDOUT, fetch/ubuntu_ apt_pkg. py:160: stderr= subprocess. STDOUT, fetch/ubuntu_ apt_pkg. py:197: stderr= subprocess. STDOUT, fetch/ubuntu_ apt_pkg. py:257: stderr= subprocess. STDOUT, contrib/ hahelpers/ cluster. py:128: status = subprocess. check_output( cmd, stderr= subprocess. STDOUT) contrib/ hahelpers/ cluster. py:161: status = subprocess. check_output( cmd, stderr= subprocess. STDOUT) contrib/ charmsupport/ nrpe.py: 438: stderr= subprocess. STDOUT contrib/ network/ ip.py:252: stderr= subprocess. STDOUT, contrib/ network/ ufw.py: 369: stderr= subprocess. STDOUT, contrib/ hardening/ host/checks/ suid_sgid. py:127: p = subprocess. Popen(cmd, stdout= subprocess. PIPE, stderr= subprocess. PIPE) contrib/ ssl/service. py:115: output = subprocess. check_output( cmd, stderr= subprocess. STDOUT) contrib/ ssl/service. py:164: subprocess. check_call( cmd, stderr= subprocess. PIPE) contrib/ ssl/service. py:166: subprocess. check_call( cmd, stderr= subprocess. PIPE) contrib/ ssl/service. py:180: subprocess. check_call( cmd, stderr= subprocess. PIPE)
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
charmhelpers/
One solution is to use the fact that the subprocess. CalledProcessEr ror class has a 'stderr' member with the output of STDERR when an exception occurs. This is available in py3.5 (xenial) but NOT in py3.4 (trusty which currently has Python 3.4.3). Obviously, that presents a slight annoyance!