Summary
aws deploy install / aws deploy uninstall (the on-premises CodeDeploy agent installer) crashes with an unhandled TypeError instead of gracefully handling the case where the codedeployagent/codedeploy-agent service does not exist yet — which is exactly the situation on a fresh host doing its first install.
Root cause
awscli/customizations/codedeploy/systems.py creates several subprocess.Popen(...) calls without text=True/universal_newlines=True:
process = subprocess.Popen(
['service', 'codedeploy-agent', 'stop'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
(output, error) = process.communicate()
if process.returncode != 0 and params.not_found_msg not in error:
raise RuntimeError(...)
Because text=True is omitted, process.communicate() returns bytes, but the code checks membership of a str literal (params.not_found_msg, or the not_found/"Running" literals in the Windows class) against that bytes object. In Python 3, "str" in b"bytes" raises TypeError: a bytes-like object is required, not 'str' — it does not evaluate to False.
Affected locations:
Windows.install (~L75): if process.returncode != 0 and not_found not in error:
Windows.install (~L108): if "Running" not in output:
Windows.uninstall (same pattern as install)
Linux._stop_agent (~L208, used by Ubuntu/RHEL install/uninstall): if process.returncode != 0 and params.not_found_msg not in error:
Reproduction
Verified by executing the real, unmodified Linux._stop_agent method against a stub service binary that reproduces the "service not registered yet" condition (exit code 1, stderr containing the expected "not found" message):
import sys
from awscli.customizations.codedeploy.systems import Linux
class Params(dict):
def __getattr__(self, k):
return self[k]
linux = Linux.__new__(Linux)
params = Params()
params['not_found_msg'] = 'codedeploy-agent: unrecognized service'
linux._stop_agent(params)
with a service script on PATH that does:
#!/bin/bash
echo "service: unrecognized service" 1>&2
exit 1
Result:
TypeError: a bytes-like object is required, not 'str'
instead of the intended graceful pass-through (or the documented RuntimeError when the failure is for a different reason).
Impact
This affects essentially every fresh aws deploy install and every aws deploy uninstall on Windows, Ubuntu, and RHEL on-premises instances — i.e. exactly the first-run scenario the not_found/not_found_msg check was written to tolerate. Instead of installing successfully or uninstalling cleanly, the command crashes with an unrelated TypeError traceback.
Suggested fix
Add text=True (or universal_newlines=True) to each subprocess.Popen(...) call in awscli/customizations/codedeploy/systems.py so communicate() returns str, matching what the existing string-membership checks assume.
Environment
Reviewed against the current aws-cli source. This is aws-cli-specific customization code (not vendored botocore).
Summary
aws deploy install/aws deploy uninstall(the on-premises CodeDeploy agent installer) crashes with an unhandledTypeErrorinstead of gracefully handling the case where thecodedeployagent/codedeploy-agentservice does not exist yet — which is exactly the situation on a fresh host doing its first install.Root cause
awscli/customizations/codedeploy/systems.pycreates severalsubprocess.Popen(...)calls withouttext=True/universal_newlines=True:Because
text=Trueis omitted,process.communicate()returnsbytes, but the code checks membership of astrliteral (params.not_found_msg, or thenot_found/"Running"literals in theWindowsclass) against thatbytesobject. In Python 3,"str" in b"bytes"raisesTypeError: a bytes-like object is required, not 'str'— it does not evaluate toFalse.Affected locations:
Windows.install(~L75):if process.returncode != 0 and not_found not in error:Windows.install(~L108):if "Running" not in output:Windows.uninstall(same pattern as install)Linux._stop_agent(~L208, used byUbuntu/RHELinstall/uninstall):if process.returncode != 0 and params.not_found_msg not in error:Reproduction
Verified by executing the real, unmodified
Linux._stop_agentmethod against a stubservicebinary that reproduces the "service not registered yet" condition (exit code 1, stderr containing the expected "not found" message):with a
servicescript onPATHthat does:Result:
instead of the intended graceful pass-through (or the documented
RuntimeErrorwhen the failure is for a different reason).Impact
This affects essentially every fresh
aws deploy installand everyaws deploy uninstallon Windows, Ubuntu, and RHEL on-premises instances — i.e. exactly the first-run scenario thenot_found/not_found_msgcheck was written to tolerate. Instead of installing successfully or uninstalling cleanly, the command crashes with an unrelatedTypeErrortraceback.Suggested fix
Add
text=True(oruniversal_newlines=True) to eachsubprocess.Popen(...)call inawscli/customizations/codedeploy/systems.pysocommunicate()returnsstr, matching what the existing string-membership checks assume.Environment
Reviewed against the current
aws-clisource. This is aws-cli-specific customization code (not vendored botocore).