Skip to content

Commit

Permalink
chg: PodsManager.stats - support stream mode
Browse files Browse the repository at this point in the history
Signed-off-by: Bharath Vignesh J K <[email protected]>
  • Loading branch information
RazCrimson committed May 25, 2023
1 parent b02001a commit a416660
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
20 changes: 16 additions & 4 deletions podman/domain/pods_manager.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""PodmanResource manager subclassed for Networks."""
import json
import logging
from typing import Any, Dict, List, Optional, Union
from typing import Any, Dict, List, Optional, Union, Iterator

from podman import api
from podman.domain.manager import Manager
Expand Down Expand Up @@ -128,12 +128,14 @@ def remove(self, pod_id: Union[Pod, str], force: Optional[bool] = None) -> None:
response = self.client.delete(f"/pods/{pod_id}", params={"force": force})
response.raise_for_status()

def stats(self, **kwargs) -> Dict[str, Any]:
def stats(self, **kwargs) -> Union[Dict[str, Any], Iterator[Dict[str, Any]]]:
"""Resource usage statistics for the containers in pods.
Keyword Args:
all (bool): Provide statistics for all running pods.
name (Union[str, List[str]]): Pods to include in report.
stream (bool): Stream statistics until cancelled. Default: False.
decode (bool): If True, response will be decoded into dict. Default: False.
Raises:
NotFound: when pod not found
Expand All @@ -142,10 +144,20 @@ def stats(self, **kwargs) -> Dict[str, Any]:
if "all" in kwargs and "name" in kwargs:
raise ValueError("Keywords 'all' and 'name' are mutually exclusive.")

# Keeping the default for stream as False to not break existing users
# Should probably be changed in a newer major version to match behavior of container.stats
stream = kwargs.get("stream", False)
decode = kwargs.get("decode", False)

params = {
"all": kwargs.get("all"),
"namesOrIDs": kwargs.get("name"),
"stream": stream,
}
response = self.client.get("/pods/stats", params=params)
response = self.client.get("/pods/stats", params=params, stream=stream)
response.raise_for_status()
return response.json()

if stream:
return api.stream_helper(response, decode_to_json=decode)

return json.loads(response.content) if decode else response.content
55 changes: 55 additions & 0 deletions podman/tests/unit/test_podsmanager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import io
import json
import unittest
from typing import Iterable

import requests_mock

Expand Down Expand Up @@ -157,6 +160,58 @@ def test_stats(self, mock):
)
self.assertDictEqual(actual, body)

@requests_mock.Mocker()
def test_top_with_streaming(self, mock):
stream = [
[
{
'CPU': '2.53%',
'MemUsage': '49.15kB / 16.71GB',
'MemUsageBytes': '48KiB / 15.57GiB',
'Mem': '0.00%',
'NetIO': '7.638kB / 430B',
'BlockIO': '-- / --',
'PIDS': '1',
'Pod': '1c948ab42339',
'CID': 'd999c49a7b6c',
'Name': '1c948ab42339-infra',
}
],
[
{
'CPU': '1.46%',
'MemUsage': '57.23B / 16.71GB',
'MemUsageBytes': '48KiB / 15.57GiB',
'Mem': '0.00%',
'NetIO': '7.638kB / 430B',
'BlockIO': '-- / --',
'PIDS': '1',
'Pod': '1c948ab42339',
'CID': 'd999c49a7b6c',
'Name': '1c948ab42339-infra',
}
],
]

buffer = io.StringIO()
for entry in stream:
buffer.write(json.JSONEncoder().encode(entry))
buffer.write("\n")

adapter = mock.get(
tests.LIBPOD_URL + "/pods/stats?stream=True",
text=buffer.getvalue(),
)

stream_results = self.client.pods.stats(stream=True, decode=True)

self.assertIsInstance(stream_results, Iterable)
for response, actual in zip(stream_results, stream):
self.assertIsInstance(response, list)
self.assertListEqual(response, actual)

self.assertTrue(adapter.called_once)

def test_stats_400(self):
with self.assertRaises(ValueError):
self.client.pods.stats(all=True, name="container")
Expand Down

0 comments on commit a416660

Please sign in to comment.