Module: check_mk
Branch: master
Commit: af6eebd81d93c27231f09124b52c1c1ecd8b8987
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=af6eebd81d93c2…
Author: Moritz Kiemer <mo(a)mathias-kettner.de>
Date: Mon Nov 5 09:17:09 2018 +0100
6836 FIX Fix Docker crashes
Work around missing 'Repository' key if Repository Tags are not defined in image
inspect output.
Work around missing values if values are zero in 'docker system df'.
Change-Id: Ie2560d04edfd15e3c7c52c3801ce6aea94a57da4
---
.werks/6836 | 12 +++++++++
checks/docker.include | 28 +++++++++++++------
inventory/docker_node_info | 2 +-
tests/unit/checks/test_docker_parse_node_images.py | 8 +++---
tests/unit/checks/test_docker_parse_node_info.py | 9 ++++++-
tests/unit/checks/test_docker_parse_system_df.py | 31 ++++++++++++++++++++++
6 files changed, 76 insertions(+), 14 deletions(-)
diff --git a/.werks/6836 b/.werks/6836
new file mode 100644
index 0000000..c6ebbe2
--- /dev/null
+++ b/.werks/6836
@@ -0,0 +1,12 @@
+Title: Fix Docker crashes
+Level: 1
+Component: checks
+Compatible: compat
+Edition: cre
+Version: 1.6.0i1
+Date: 1541405122
+Class: fix
+
+Work around missing 'Repository' key if Repository Tags are not defined in image
inspect output.
+Work around missing values if values are zero in 'docker system df'.
+Do not crash upon empty section in case of missing permissions.
diff --git a/checks/docker.include b/checks/docker.include
index 3b23b69..01b6bf8 100644
--- a/checks/docker.include
+++ b/checks/docker.include
@@ -71,15 +71,21 @@ def _docker_trunc_id(hash_string):
def _get_repo_tag(string):
if ":" in string:
- return tuple(string.split(":", 1))
+ return tuple(string.rsplit(":", 1))
return string, "latest"
def parse_docker_node_info(info):
'''parse output of "docker info"'''
+ if not info:
+ return {}
+
+ # parse legacy json output (verisons 1.5.0 - 1.5.0p6)
+ joined = " ".join(info[0])
+ if joined.endswith("permission denied"):
+ return {}
try:
- # parse legacy json output (verisons 1.5.0 - 1.5.0p6)
- return json.loads(" ".join(info[0]))
+ return json.loads(joined)
except ValueError:
pass
@@ -169,10 +175,13 @@ def _docker_parse_table(rows, fields, keys):
def parse_docker_system_df(info):
+ def int_or_zero(s):
+ return int(s.strip() or 0)
+
field_map = (
('TYPE', 'TOTAL', 'ACTIVE', 'SIZE',
'RECLAIMABLE'),
('Type', 'TotalCount', 'Active', 'Size',
'Reclaimable'),
- (str, int, int, _docker_get_bytes, _docker_get_bytes),
+ (str, int_or_zero, int_or_zero, _docker_get_bytes, _docker_get_bytes),
)
try: # parse legacy json output: from 1.5.0 - 1.5.0p6
@@ -292,6 +301,9 @@ def parse_docker_node_images(info):
repotags = pref_info.get("RepoTags")
if repotags:
image["Repository"], image["Tag"] =
_get_repo_tag(repotags[-1])
+ else:
+ repo = pref_info.get("RepoDigest", "").split('@',
1)[0]
+ image["Repository"], image["Tag"] = _get_repo_tag(repo)
for image in images.itervalues():
image["amount_containers"] = 0
@@ -305,15 +317,15 @@ def parse_docker_node_images(info):
mapping = {(i['Repository'], i['Tag']): i['ID']
for i in images.itervalues()}
- for c in containers.itervalues():
- image_id = mapping.get((c["Repository"], c["Tag"]))
+ for cont in containers.itervalues():
+ image_id = mapping.get((cont["Repository"], cont["Tag"]))
image = images.get(image_id)
if image is not None:
image["amount_containers"] += 1
- labels = c.get("Labels")
+ labels = cont.get("Labels")
if isinstance(labels, (str, unicode)):
- c["Labels"] = parse_docker_messed_up_labels(labels)
+ cont["Labels"] = parse_docker_messed_up_labels(labels)
return {"images": images, "containers": containers}
diff --git a/inventory/docker_node_info b/inventory/docker_node_info
index a7da959..b95dfef 100644
--- a/inventory/docker_node_info
+++ b/inventory/docker_node_info
@@ -27,7 +27,7 @@
def inv_docker_node_info(parsed, inventory_tree, status_data_tree):
- if not isinstance(parsed, dict):
+ if not parsed or not isinstance(parsed, dict):
# String with error message in case the daemon is not running
return
diff --git a/tests/unit/checks/test_docker_parse_node_images.py
b/tests/unit/checks/test_docker_parse_node_images.py
index 4cd1318..6588b56 100644
--- a/tests/unit/checks/test_docker_parse_node_images.py
+++ b/tests/unit/checks/test_docker_parse_node_images.py
@@ -6539,10 +6539,10 @@ EXPECTED_IMAGES3 = {
u'CreatedSince': u'3 days ago',
u'Digest': u'<none>',
u'ID': u'0983f5184ce7',
- u'Repository': u'<none>',
+ u'Repository': u'',
u'SharedSize': u'N/A',
u'Size': u'312MB',
- u'Tag': u'<none>',
+ u'Tag': u'latest',
u'UniqueSize': u'N/A',
u'VirtualSize': 312404556,
'__labels__': {
@@ -6896,10 +6896,10 @@ EXPECTED_IMAGES3 = {
u'CreatedSince': u'6 days ago',
u'Digest': u'<none>',
u'ID': u'df118e583614',
- u'Repository': u'<none>',
+ u'Repository': u'',
u'SharedSize': u'N/A',
u'Size': u'818MB',
- u'Tag': u'<none>',
+ u'Tag': u'latest',
u'UniqueSize': u'N/A',
u'VirtualSize': 817561911,
'__labels__': {
diff --git a/tests/unit/checks/test_docker_parse_node_info.py
b/tests/unit/checks/test_docker_parse_node_info.py
index 7ba3e8c..a8c3432 100644
--- a/tests/unit/checks/test_docker_parse_node_info.py
+++ b/tests/unit/checks/test_docker_parse_node_info.py
@@ -312,7 +312,14 @@ execfile(os.path.join(os.path.dirname(__file__),
'../../../checks/docker.include
"ContainersRunning": 1,
"ContainersStopped": 1,
"ContainersPaused": 0,
- })
+ }),
+ ([[u'Got', u'permission', u'denied', u'while',
u'trying', u'to', u'connect',
+ u'to', u'the', u'Docker', u'daemon',
u'socket', u'at',
+ u'unix:///var/run/docker.sock:', u'Get',
+ u'http://%2Fvar%2Frun%2Fdocker.sock/v1.26/info:', u'dial',
u'unix',
+ u'/var/run/docker.sock:', u'connect:', u'permission',
u'denied']
+ ], {}),
+ ([], {}),
])
def test_parse_docker_node_info(indata, outdata_subset):
diff --git a/tests/unit/checks/test_docker_parse_system_df.py
b/tests/unit/checks/test_docker_parse_system_df.py
index 80d76a4..a9dd43f 100644
--- a/tests/unit/checks/test_docker_parse_system_df.py
+++ b/tests/unit/checks/test_docker_parse_system_df.py
@@ -39,6 +39,37 @@ regex = re.compile
['Images 15 2 9.57GB
8.674GB (90%)'],
['Containers 2 1 1.226GB
1.224GB (99%)'],
['Local Volumes 1 1 9.323MB
0B (0%)'],
+ ['Build Cache 0B
0B'],
+ ], {"images": {
+ "Type": "Images",
+ "TotalCount": 15,
+ "Active": 2,
+ "Size": 9570000000,
+ "Reclaimable": 8674000000},
+ "containers": {
+ "Type": "Containers",
+ "TotalCount": 2,
+ "Active": 1,
+ "Size": 1226000000,
+ "Reclaimable": 1224000000},
+ "local volumes": {
+ "Type": "Local Volumes",
+ "TotalCount": 1,
+ "Active": 1,
+ "Size": 9323000,
+ "Reclaimable": 0},
+ "build cache": {
+ "Type": "Build Cache",
+ "TotalCount": 0,
+ "Active": 0,
+ "Size": 0,
+ "Reclaimable": 0},
+ }),
+ ([
+ ['TYPE TOTAL ACTIVE SIZE
RECLAIMABLE'],
+ ['Images 15 2 9.57GB
8.674GB (90%)'],
+ ['Containers 2 1 1.226GB
1.224GB (99%)'],
+ ['Local Volumes 1 1 9.323MB
0B (0%)'],
['Build Cache 0 0 0B
0B'],
], {"images": {
"Type": "Images",