diff --git a/README.md b/README.md index d54e7c9..2290066 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,20 @@ scheduler. * Can create a size-limited rotated logfile. * Can send notification emails after each run or only for failures. * Can run `scrub` after `sync` +* Can run `smart`. For this to work, you need [smartmontools](https://www.smartmontools.org/wiki/Download). + Most Linux distributions will have it installed installed by default. + * Windows users may install using the packaged .exe installer found at this link or + use [Chocolatey](https://chocolatey.org/) (i.e., `choco install smartmontools`). + * Mac OS users may install using the packaged .dmg installer found at this link or + use [Homebrew](https://brew.sh/) (i.e., `brew install smartmontools`). + * Linux users may check for smartmontools using `smartctl -V`, if not installed use + your distribution's package manager to install `smartmontools` + (e.g., `apt-get install smartmontools`, `yum install smartmontools`, etc.) ## Changelog ### Unreleased * Add support for running `snapraid touch` (by ShoGinn, PR-11) +* Add support for running `snapraid smart` (by k3vmcd, PR-15) ### v0.3 (20 Jul 2017) * Limit size of sent emails diff --git a/snapraid-runner.conf.example b/snapraid-runner.conf.example index dce416f..c2ba061 100644 --- a/snapraid-runner.conf.example +++ b/snapraid-runner.conf.example @@ -5,8 +5,10 @@ executable = snapraid config = snapraid.conf ; abort operation if there are more deletes than this, set to -1 to disable deletethreshold = 40 -; if you want touch to be ran each time +; set to true to run touch each time touch = false +; set to true to run smart. Make sure smartctl is in your PATH +smart = false [logging] ; logfile to write to, leave empty to disable diff --git a/snapraid-runner.py b/snapraid-runner.py index 5ea96b5..724c6e8 100644 --- a/snapraid-runner.py +++ b/snapraid-runner.py @@ -39,7 +39,7 @@ def tee_thread(): return t -def snapraid_command(command, args={}, ignore_errors=False): +def snapraid_command(command, args={}, ignore_errors=False, stdout_log_level=None): """ Run snapraid command Raises subprocess.CalledProcessError if errorlevel != 0 @@ -53,7 +53,7 @@ def snapraid_command(command, args={}, ignore_errors=False): stderr=subprocess.PIPE) out = [] threads = [ - tee_log(p.stdout, out, logging.OUTPUT), + tee_log(p.stdout, out, stdout_log_level or logging.OUTPUT), tee_log(p.stderr, [], logging.OUTERR)] for t in threads: t.join() @@ -132,7 +132,7 @@ def load_config(args): global config parser = ConfigParser.RawConfigParser() parser.read(args.conf) - sections = ["snapraid", "logging", "email", "smtp", "scrub"] + sections = ["snapraid", "logging", "email", "smtp", "scrub", "smart"] config = dict((x, defaultdict(lambda: "")) for x in sections) for section in parser.sections(): for (k, v) in parser.items(section): @@ -152,6 +152,7 @@ def load_config(args): config["scrub"]["enabled"] = (config["scrub"]["enabled"].lower() == "true") config["email"]["short"] = (config["email"]["short"].lower() == "true") config["snapraid"]["touch"] = (config["snapraid"]["touch"].lower() == "true") + config["snapraid"]["smart"] = (config["snapraid"]["smart"].lower() == "true") if args.scrub is not None: config["scrub"]["enabled"] = args.scrub @@ -163,6 +164,9 @@ def setup_logger(): root_logger = logging.getLogger() logging.OUTPUT = 15 logging.addLevelName(logging.OUTPUT, "OUTPUT") + # We only run smart for its output, so we always include it + logging.SMART = 24 + logging.addLevelName(logging.SMART, "SMART") logging.OUTERR = 25 logging.addLevelName(logging.OUTERR, "OUTERR") root_logger.setLevel(logging.OUTPUT) @@ -288,6 +292,15 @@ def run(): finish(False) logging.info("*" * 60) + if config["snapraid"]["smart"]: + logging.info("Running SMART...") + try: + snapraid_command("smart", stdout_log_level=logging.SMART) + except subprocess.CalledProcessError as e: + logging.error(e) + finish(False) + logging.info("*" * 60) + logging.info("All done") finish(True)