-
Notifications
You must be signed in to change notification settings - Fork 329
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
Handle empty stdout properly in MinioAdmin #1099
Conversation
@@ -50,7 +50,7 @@ def _run(self, args, multiline=False): | |||
check=True, |
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.
Add text=True
get proc.stdout
as string and treat it as string later.
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.
Done
@cbows
On which admin API do you get this error? |
I got it on |
@@ -48,9 +48,10 @@ def _run(self, args, multiline=False): | |||
capture_output=True, | |||
timeout=self._timeout, | |||
check=True, | |||
text=True, | |||
) |
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.
Add a fix generically to avoid any error on json.loads()
here
if not proc.stdout:
return [] if multiline 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.
Ok
minio/minioadmin.py
Outdated
if multiline: | ||
return [json.loads(line) for line in proc.stdout.split("\n")] | ||
return [json.loads(line) for line in proc.stdout.split("\n") if line] |
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.
No change required in this line.
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 error I had actually occurs when proc.stdout is not empty, but has an empty b""
after split
.
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.
Here is an example:
The response:
'{"status":"success","policy":"diagnostics","isGroup":false}\n{"status":"success","policy":"readonly","isGroup":false}\n{"status":"success","policy":"readwrite","isGroup":false}\n{"status":"success","policy":"writeonly","isGroup":false}\n'
becomes
['{"status":"success","policy":"diagnostics","isGroup":false}',
'{"status":"success","policy":"readonly","isGroup":false}',
'{"status":"success","policy":"readwrite","isGroup":false}',
'{"status":"success","policy":"writeonly","isGroup":false}',
'']
which fails at the very end because the trailing new-line results in empty string.
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.
you could also do something like proc.stdout.strip().split("\n")
to get rid of any leading/trailing whitespace.
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.
Use .splitlines()
instead of .split("\n")
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.
That still doesn't handle cases where response is "a\n\nb\nc\n"
, but it's good enough for me.
To avoid empty strings after splitting `proc.stdout`, `splitlines` is used instead of `split`. To avoid errors when `proc.stdout` itself is empty, an additional guard has been added. In this case, an empty list or dictionary is returned, depending on `multiline`. Also, `text=True` is passed `subprocess.run` to ensure `proc.stdout` is a string and not bytes object.
json.loads(line)
would throw an error if line is empty (e.g.line == b''
).To fix it, simply check if line is truthy (i.e. not empty).
Also, since
proc.stdout
is of typebytes
the argument passed toproc.stdout.split
was changed tob"\n"
.