Skip to content
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

Merged
merged 1 commit into from
May 24, 2021

Conversation

bo5o
Copy link
Contributor

@bo5o bo5o commented Mar 23, 2021

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 type bytes the argument passed to
proc.stdout.split was changed to b"\n".

@@ -50,7 +50,7 @@ def _run(self, args, multiline=False):
check=True,
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@balamurugana
Copy link
Member

@cbows

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).

On which admin API do you get this error?

@bo5o
Copy link
Contributor Author

bo5o commented Mar 23, 2021

I got it on policy_list, which had an empty b'' as the last item in the list.

@@ -48,9 +48,10 @@ def _run(self, args, multiline=False):
capture_output=True,
timeout=self._timeout,
check=True,
text=True,
)
Copy link
Member

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 {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

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]
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Member

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")

Copy link
Contributor Author

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.

@balamurugana balamurugana changed the title fix bug when there is an empty line in mc admin response Handle empty stdout properly in MinioAdmin Mar 23, 2021
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.
@harshavardhana harshavardhana merged commit 0e5a62e into minio:master May 24, 2021
@bo5o bo5o deleted the fix-empty-line branch May 28, 2021 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants