-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to run command #2022
Switch to run command #2022
Conversation
… everything that needs changing.
shellutil.run_command(["eject", dvd]) | ||
except shellutil.CommandError as cmd_err: | ||
if chk_err: | ||
raise OSUtilError("Failed to eject dvd: ret={0}".format(cmd_err.returncode)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably add the stdout/stderr of the command (the original code was logging errors)
else: | ||
logger.warn("exceeded restart retries") | ||
except shellutil.CommandError as cmd_err: | ||
logger.warn("failed to restart {0}: return code {1}".format(ifname, cmd_err.returncode)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should add the stdout/stderr of the command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is small difference here in that the previous code would log commands errors as INFO if the return code was 1, and as ERROR otherwise.
Since anyways we are logging a WARN regardless of the return code, I think we are OK here (as long as we add stderr/stdout to the message)
"-days", "730", "-newkey", "rsa:2048", "-keyout", prv_file, "-out", crt_file] | ||
try: | ||
shellutil.run_command(cmd) | ||
except shellutil.CommandError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log stdout/stderr
second_proc = subprocess.Popen(second_cmd, stdin=first_proc.stdout, stdout=subprocess.PIPE) | ||
second_proc.wait() | ||
|
||
if first_proc.returncode or second_proc.returncode: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's do an explicit comparison against 0
|
||
first_proc = subprocess.Popen(first_cmd, stdout=subprocess.PIPE) | ||
second_proc = subprocess.Popen(second_cmd, stdin=first_proc.stdout, stdout=subprocess.PIPE) | ||
second_proc.wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should use communicate() instead to get stdout/stderr and log it on failure
output_file)) | ||
try: | ||
with open(output_file, "a") as file_out: | ||
output = shellutil.run_command(["ssh-keygen", "-i -m PKCS8 -f", input_file]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would feel more comfortable if we use Popen directly here (as we did in the previous function). run_command has some extra code to encode the command's output and, though I do not see any issue right now, I think it would be safer to use Popen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments
[stderr] | ||
{3} | ||
""".format(ifname, cmd_err.returncode, cmd_err.stdout, cmd_err.stderr) | ||
logger.warn(msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the previous implementation, the exit_code:1 was logged as an info if there were retries available and then as an error. Now you're just logging it as a warning, not sure if you want to keep them consistent or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this logged in L1154?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope that's a different log line. I was comparing the previous implementation with the new one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically this parameter for expected_errors=[1]
in the previous implementation -
return_code=shellutil.run("ifdown {0} && ifup {0}".format(ifname), expected_errors=[1] if attempt < retries else [])
The shellutil.run
function would've logged it as an info if the exit_code was 1 but now it would be logged as an error.
Not sure how big of a difference it makes, just noticed it so figured I'd point it out. I'm personally fine as is too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@larohra I posted a similar comment here, not sure why it doesn't show up.
In any case, I added the 'expected_errors' parameter some time back as a stopgap to avoid logging an error when the error code is 1. This seems to be relatively common and was logged as an error due to the way the run() function is defined, and this was confusing people looking at the log. From the caller, any error code executing the command is clearly a warning.
The new implementation drops the INFO (which was there just because run logs all failures in the command it execurtes), but keeps the warning. This should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh ok ok, makes sense. Thanks for the clarification
"-out", pem_file] | ||
|
||
first_proc = subprocess.Popen(first_cmd, stdout=subprocess.PIPE) | ||
second_proc = subprocess.Popen(second_cmd, stdin=first_proc.stdout, stdout=subprocess.PIPE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good way of solving the problem! I'm sure you must've already done this, but you confirmed this has no regressions right? And DCR passed too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kevinclark19a DCR ok?
|
||
[stderr] | ||
{2} | ||
""".format(p7m_file, stdout, stderr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to encode the stdout/stderr before writing it to log (the run_command function always does that for you)
tests/common/osutil/test_default.py
Outdated
self.assertEqual(cmd_queue.pop(0), ["ifdown", ifname]) | ||
# We don't expect the following command to be called because 'dummy' does | ||
# not exist. | ||
# self.assertEqual(cmd_queue.pop(0), ["ifup", ifname]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you dont expect this, you should add an assert that it's actually not called rather than a comment :)
with patch.object(os, 'makedirs'): | ||
try: | ||
osutil.DefaultOSUtil().mount_dvd() | ||
self.fail('OSUtilError was not raised') | ||
except OSUtilError as ose: | ||
self.assertTrue(msg in ustr(ose)) | ||
self.assertTrue(patch_run.call_count == 6) | ||
self.assertEqual(patch_run.call_count, 5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did the number of calls change if we didn't change the retry number (6)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The range has always been [1..6)
, so I'm not quite sure how this test was passing before. Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok I figured it out. Before, we were mocking run_get_output
, because that's what self.mount
used before. There is a run_get_output
call in mount_dvd
that we decided not to bother changing as a part of this PR (as it uses a constant string), which was the 6th call before. Since our mock is now for run_command
, that run_get_output
call obviously doesn't get counted anymore, bringing the total number of calls from 6 (5 run_get_output
calls in self.mount
+ 1 run_get_output
in mount_dvd
itself) to 5 (just the five run_command
calls in self.mount
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for checking! Makes sense now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments, else LGTM
…Agent into SwitchToRunCommand
@@ -96,6 +96,9 @@ def decrypt_p7m(self, p7m_file, trans_prv_file, trans_cert_file, pem_file): | |||
stdout, stderr = second_proc.communicate() | |||
|
|||
if first_proc.returncode != 0 or second_proc.returncode != 0: | |||
stdout = ustr(stdout, encoding='utf-8', errors="backslashreplace") if stdout else "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: How about making this function public and using this instead -
def _encode_command_output(output):
return ustr(output, encoding='utf-8', errors="backslashreplace")
Its in the shellutils.py
This reverts commit 7c8ed71.
This reverts commit f90227f.
… reverted. (#2050) * Temporarily removing the depreciated functions to let the linter find everything that needs changing. * Migrated run_get_output to run_command * Fixed typo * Fixed arg formatting issues. * Fixed file mode. * fixed some unit tests * Potentially fixed unit tests? * Fixed file name * Addressed comments * Fixed comments * fixed tests. * Added logging * Potentially fixed bug * Removing debugging log. * Fixed bug with run_command needing a list instead of a string. * Added logging statement for debugging. * Fixed tests * Revert "Revert "Switch to run command (#2022)" (#2039)" This reverts commit f90227f. * Reverted unneeded changes. * Potential fix for DCR provisioning failure. * added logging for errors. * Addressed PR comments.
Description
Switched a set of
shellutil.run_get_output
andshellutil.run
callers to the newshellutil.run_command
function.PR information
Quality of Code and Contribution Guidelines