From 3a2fcb1abfb79ddb3dd943f09f2bf203f335b6c4 Mon Sep 17 00:00:00 2001 From: Alex Boag-Munroe Date: Thu, 26 Sep 2019 00:25:18 +0100 Subject: [PATCH 1/4] Support parsing zpool output for ZFS >=0.8.0 Query /sys/module/zfs/version for ZFS version and account for the additional CKPOINT field in ZFS 0.8.0 and higher. --- bumblebee/modules/zpool.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bumblebee/modules/zpool.py b/bumblebee/modules/zpool.py index 701c1c1..5b6092a 100644 --- a/bumblebee/modules/zpool.py +++ b/bumblebee/modules/zpool.py @@ -25,6 +25,7 @@ Be aware of security implications of doing this! """ import time +from pkg_resources import parse_version import bumblebee.engine from bumblebee.util import execute, bytefmt, asbool @@ -64,6 +65,8 @@ class Module(bumblebee.engine.Module): def _update_widgets(self, widgets): # zpool list -H: List all zpools, use script mode (no headers and tabs as separators). + with open('/sys/module/zfs/version', 'r') as zfs_mod_version: + zfs_version = zfs_mod_version.readline().rstrip().split('-')[0] raw_zpools = execute(('sudo ' if self._usesudo else '') + 'zpool list -H').split('\n') for widget in widgets: @@ -71,8 +74,11 @@ class Module(bumblebee.engine.Module): for raw_zpool in raw_zpools: try: - # Ignored fields (assigned to _) are "expandsz" and "altroot" - name, size, alloc, free, _, frag, cap, dedup, health, _ = raw_zpool.split('\t') + # Ignored fields (assigned to _) are "expandsz" and "altroot", also "ckpoint" in ZFS 0.8.0+ + if parse_version(zfs_version) < parse_version("0.8.0"): + name, size, alloc, free, _, frag, cap, dedup, health, _ = raw_zpool.split('\t') + else: + name, size, alloc, free, _, _, frag, cap, dedup, health, _ = raw_zpool.split('\t') cap = cap.rstrip('%') percentuse=int(cap) percentfree=100-percentuse From fd990eb4fde0e206ca7898681395e6b966c81f83 Mon Sep 17 00:00:00 2001 From: Alex Boag-Munroe Date: Thu, 26 Sep 2019 23:22:25 +0100 Subject: [PATCH 2/4] Don't crash when ZFS version info is unavailable Catch the FileNotFoundError and stub the zfs version for the script to not crash. --- bumblebee/modules/zpool.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bumblebee/modules/zpool.py b/bumblebee/modules/zpool.py index 5b6092a..b8569df 100644 --- a/bumblebee/modules/zpool.py +++ b/bumblebee/modules/zpool.py @@ -65,8 +65,13 @@ class Module(bumblebee.engine.Module): def _update_widgets(self, widgets): # zpool list -H: List all zpools, use script mode (no headers and tabs as separators). - with open('/sys/module/zfs/version', 'r') as zfs_mod_version: - zfs_version = zfs_mod_version.readline().rstrip().split('-')[0] + try: + with open('/sys/module/zfs/version', 'r') as zfs_mod_version: + zfs_version = zfs_mod_version.readline().rstrip().split('-')[0] + except FileNotFoundError: + # ZFS isn't installed or the module isn't loaded, stub the version + zfs_version = "0.0.0" + raw_zpools = execute(('sudo ' if self._usesudo else '') + 'zpool list -H').split('\n') for widget in widgets: From e44eea3318d62c956d36aef115ee4786848418f4 Mon Sep 17 00:00:00 2001 From: Alex Boag-Munroe Date: Thu, 26 Sep 2019 23:30:06 +0100 Subject: [PATCH 3/4] Log when unable to ascertain ZFS version Use established logging strategy to emit an error log when ZFS version information cannot be obtained. --- bumblebee/modules/zpool.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bumblebee/modules/zpool.py b/bumblebee/modules/zpool.py index b8569df..e5f42c6 100644 --- a/bumblebee/modules/zpool.py +++ b/bumblebee/modules/zpool.py @@ -25,10 +25,12 @@ Be aware of security implications of doing this! """ import time +import logging from pkg_resources import parse_version import bumblebee.engine from bumblebee.util import execute, bytefmt, asbool +log = logging.getLogger(__name__) class Module(bumblebee.engine.Module): def __init__(self, engine, config): @@ -64,13 +66,15 @@ class Module(bumblebee.engine.Module): return state def _update_widgets(self, widgets): + zfs_version_path = "/sys/module/zfs/version" # zpool list -H: List all zpools, use script mode (no headers and tabs as separators). try: - with open('/sys/module/zfs/version', 'r') as zfs_mod_version: + with open(zfs_version_path, 'r') as zfs_mod_version: zfs_version = zfs_mod_version.readline().rstrip().split('-')[0] except FileNotFoundError: # ZFS isn't installed or the module isn't loaded, stub the version zfs_version = "0.0.0" + logging.error("ZFS version information not found at {}, check the module is loaded.".format(zfs_version_path)) raw_zpools = execute(('sudo ' if self._usesudo else '') + 'zpool list -H').split('\n') From ffac34a51c8393c42226f3f1deacffb7db26de6f Mon Sep 17 00:00:00 2001 From: Alex Boag-Munroe Date: Thu, 26 Sep 2019 23:40:41 +0100 Subject: [PATCH 4/4] Catch IOError for backwards compatability FileNotFoundError is not in Python 2, catch IOError instead. --- bumblebee/modules/zpool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bumblebee/modules/zpool.py b/bumblebee/modules/zpool.py index e5f42c6..1f3e897 100644 --- a/bumblebee/modules/zpool.py +++ b/bumblebee/modules/zpool.py @@ -71,7 +71,7 @@ class Module(bumblebee.engine.Module): try: with open(zfs_version_path, 'r') as zfs_mod_version: zfs_version = zfs_mod_version.readline().rstrip().split('-')[0] - except FileNotFoundError: + except IOError: # ZFS isn't installed or the module isn't loaded, stub the version zfs_version = "0.0.0" logging.error("ZFS version information not found at {}, check the module is loaded.".format(zfs_version_path))