summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/diskprediction_local
diff options
context:
space:
mode:
Diffstat (limited to 'src/pybind/mgr/diskprediction_local')
-rw-r--r--src/pybind/mgr/diskprediction_local/__init__.py2
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/config.json77
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_1.pklbin0 -> 281292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_10.pklbin0 -> 217792 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_104.pklbin0 -> 492492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_105.pklbin0 -> 217192 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_109.pklbin0 -> 256392 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_112.pklbin0 -> 499492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_114.pklbin0 -> 276492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_115.pklbin0 -> 509592 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_118.pklbin0 -> 315192 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_119.pklbin0 -> 485992 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_12.pklbin0 -> 275692 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_120.pklbin0 -> 307592 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_123.pklbin0 -> 246792 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_124.pklbin0 -> 310292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_125.pklbin0 -> 452492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_128.pklbin0 -> 550492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_131.pklbin0 -> 493192 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_134.pklbin0 -> 266692 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_138.pklbin0 -> 488292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_14.pklbin0 -> 244892 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_141.pklbin0 -> 422368 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_145.pklbin0 -> 359512 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_151.pklbin0 -> 305944 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_16.pklbin0 -> 308192 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_161.pklbin0 -> 305188 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_168.pklbin0 -> 301516 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_169.pklbin0 -> 363400 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_174.pklbin0 -> 323764 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_18.pklbin0 -> 312692 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_182.pklbin0 -> 354652 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_185.pklbin0 -> 317176 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_186.pklbin0 -> 276352 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_195.pklbin0 -> 489544 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_201.pklbin0 -> 307888 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_204.pklbin0 -> 567088 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_206.pklbin0 -> 474856 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_208.pklbin0 -> 283588 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_210.pklbin0 -> 617200 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_212.pklbin0 -> 345148 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_213.pklbin0 -> 357568 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_219.pklbin0 -> 342232 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_221.pklbin0 -> 365128 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_222.pklbin0 -> 314800 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_223.pklbin0 -> 342124 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_225.pklbin0 -> 329812 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_227.pklbin0 -> 296440 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_229.pklbin0 -> 572380 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_230.pklbin0 -> 251188 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_234.pklbin0 -> 277972 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_235.pklbin0 -> 243736 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_236.pklbin0 -> 377872 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_239.pklbin0 -> 571732 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_243.pklbin0 -> 534148 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_27.pklbin0 -> 504592 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_3.pklbin0 -> 557192 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_33.pklbin0 -> 547392 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_36.pklbin0 -> 516692 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_44.pklbin0 -> 546592 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_50.pklbin0 -> 448292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_57.pklbin0 -> 328292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_59.pklbin0 -> 494292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_6.pklbin0 -> 314092 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_61.pklbin0 -> 499492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_62.pklbin0 -> 483492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_67.pklbin0 -> 492592 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_69.pklbin0 -> 288292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_71.pklbin0 -> 228792 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_72.pklbin0 -> 489492 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_78.pklbin0 -> 491392 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_79.pklbin0 -> 284992 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_82.pklbin0 -> 255292 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_85.pklbin0 -> 522092 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_88.pklbin0 -> 502392 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_93.pklbin0 -> 302592 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/prophetstor/svm_97.pklbin0 -> 272392 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/redhat/config.json4
-rw-r--r--src/pybind/mgr/diskprediction_local/models/redhat/hgst_predictor.pklbin0 -> 2860606 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/redhat/hgst_scaler.pklbin0 -> 1865 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/redhat/seagate_predictor.pklbin0 -> 37062936 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/models/redhat/seagate_scaler.pklbin0 -> 1481 bytes
-rw-r--r--src/pybind/mgr/diskprediction_local/module.py305
-rw-r--r--src/pybind/mgr/diskprediction_local/predictor.py484
-rw-r--r--src/pybind/mgr/diskprediction_local/requirements.txt3
85 files changed, 875 insertions, 0 deletions
diff --git a/src/pybind/mgr/diskprediction_local/__init__.py b/src/pybind/mgr/diskprediction_local/__init__.py
new file mode 100644
index 000000000..ee85dc9d3
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/__init__.py
@@ -0,0 +1,2 @@
+# flake8: noqa
+from .module import Module
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/config.json b/src/pybind/mgr/diskprediction_local/models/prophetstor/config.json
new file mode 100644
index 000000000..9a1485ca3
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/config.json
@@ -0,0 +1,77 @@
+{
+"svm_123.pkl": ["smart_197_raw", "smart_183_raw", "smart_200_raw", "smart_194_raw", "smart_254_raw", "smart_252_raw", "smart_4_raw", "smart_222_raw", "smart_187_raw", "smart_184_raw"],
+"svm_105.pkl": ["smart_197_raw", "smart_4_raw", "smart_5_raw", "smart_252_raw", "smart_184_raw", "smart_223_raw", "smart_198_raw", "smart_10_raw", "smart_189_raw", "smart_222_raw"],
+"svm_82.pkl":["smart_184_raw", "smart_2_raw", "smart_187_raw", "smart_225_raw", "smart_198_raw", "smart_197_raw", "smart_4_raw", "smart_13_raw", "smart_188_raw", "smart_251_raw"],
+"svm_186.pkl":["smart_3_raw", "smart_11_raw", "smart_198_raw", "smart_250_raw", "smart_13_raw", "smart_200_raw", "smart_224_raw", "smart_187_raw", "smart_22_raw", "smart_4_raw", "smart_220_raw"],
+"svm_14.pkl":["smart_12_raw", "smart_226_raw", "smart_187_raw", "smart_196_raw", "smart_5_raw", "smart_183_raw", "smart_255_raw", "smart_250_raw", "smart_201_raw", "smart_8_raw"],
+"svm_10.pkl":["smart_251_raw", "smart_4_raw", "smart_223_raw", "smart_13_raw", "smart_255_raw", "smart_188_raw", "smart_197_raw", "smart_201_raw", "smart_250_raw", "smart_15_raw"],
+"svm_235.pkl":["smart_15_raw", "smart_255_raw", "smart_252_raw", "smart_197_raw", "smart_250_raw", "smart_254_raw", "smart_13_raw", "smart_251_raw", "smart_198_raw", "smart_189_raw", "smart_191_raw"],
+"svm_234.pkl":["smart_187_raw", "smart_183_raw", "smart_3_raw", "smart_4_raw", "smart_222_raw", "smart_184_raw", "smart_5_raw", "smart_198_raw", "smart_200_raw", "smart_8_raw", "smart_10_raw"],
+"svm_119.pkl":["smart_254_raw", "smart_8_raw", "smart_183_raw", "smart_184_raw", "smart_195_raw", "smart_252_raw", "smart_191_raw", "smart_10_raw", "smart_200_raw", "smart_197_raw"],
+"svm_227.pkl":["smart_254_raw", "smart_189_raw", "smart_225_raw", "smart_224_raw", "smart_197_raw", "smart_223_raw", "smart_4_raw", "smart_183_raw", "smart_11_raw", "smart_184_raw", "smart_13_raw"],
+"svm_18.pkl":["smart_197_raw", "smart_3_raw", "smart_220_raw", "smart_193_raw", "smart_10_raw", "smart_187_raw", "smart_188_raw", "smart_225_raw", "smart_194_raw", "smart_13_raw"],
+"svm_78.pkl":["smart_10_raw", "smart_183_raw", "smart_191_raw", "smart_13_raw", "smart_198_raw", "smart_22_raw", "smart_195_raw", "smart_12_raw", "smart_224_raw", "smart_200_raw"],
+"svm_239.pkl":["smart_3_raw", "smart_254_raw", "smart_199_raw", "smart_225_raw", "smart_187_raw", "smart_195_raw", "smart_197_raw", "smart_2_raw", "smart_193_raw", "smart_220_raw", "smart_183_raw"],
+"svm_174.pkl":["smart_183_raw", "smart_196_raw", "smart_225_raw", "smart_189_raw", "smart_4_raw", "smart_3_raw", "smart_9_raw", "smart_198_raw", "smart_15_raw", "smart_5_raw", "smart_194_raw"],
+"svm_104.pkl":["smart_12_raw", "smart_198_raw", "smart_197_raw", "smart_4_raw", "smart_240_raw", "smart_187_raw", "smart_225_raw", "smart_8_raw", "smart_3_raw", "smart_2_raw"],
+"svm_12.pkl":["smart_222_raw", "smart_251_raw", "smart_194_raw", "smart_9_raw", "smart_184_raw", "smart_191_raw", "smart_187_raw", "smart_255_raw", "smart_4_raw", "smart_11_raw"],
+"svm_97.pkl":["smart_15_raw", "smart_197_raw", "smart_190_raw", "smart_199_raw", "smart_200_raw", "smart_12_raw", "smart_191_raw", "smart_254_raw", "smart_194_raw", "smart_201_raw"],
+"svm_118.pkl":["smart_11_raw", "smart_225_raw", "smart_196_raw", "smart_197_raw", "smart_198_raw", "smart_200_raw", "smart_3_raw", "smart_10_raw", "smart_191_raw", "smart_22_raw"],
+"svm_185.pkl":["smart_191_raw", "smart_254_raw", "smart_3_raw", "smart_190_raw", "smart_15_raw", "smart_22_raw", "smart_2_raw", "smart_198_raw", "smart_13_raw", "smart_226_raw", "smart_225_raw"],
+"svm_206.pkl":["smart_183_raw", "smart_192_raw", "smart_197_raw", "smart_255_raw", "smart_187_raw", "smart_254_raw", "smart_198_raw", "smart_13_raw", "smart_226_raw", "smart_240_raw", "smart_8_raw"],
+"svm_225.pkl":["smart_224_raw", "smart_11_raw", "smart_5_raw", "smart_4_raw", "smart_225_raw", "smart_197_raw", "smart_15_raw", "smart_183_raw", "smart_193_raw", "smart_190_raw", "smart_187_raw"],
+"svm_169.pkl":["smart_252_raw", "smart_183_raw", "smart_254_raw", "smart_11_raw", "smart_193_raw", "smart_22_raw", "smart_226_raw", "smart_189_raw", "smart_225_raw", "smart_198_raw", "smart_200_raw"],
+"svm_79.pkl":["smart_184_raw", "smart_196_raw", "smart_4_raw", "smart_226_raw", "smart_199_raw", "smart_187_raw", "smart_193_raw", "smart_188_raw", "smart_12_raw", "smart_250_raw"],
+"svm_69.pkl":["smart_187_raw", "smart_9_raw", "smart_200_raw", "smart_11_raw", "smart_252_raw", "smart_189_raw", "smart_4_raw", "smart_188_raw", "smart_255_raw", "smart_201_raw"],
+"svm_201.pkl":["smart_224_raw", "smart_8_raw", "smart_250_raw", "smart_2_raw", "smart_198_raw", "smart_15_raw", "smart_193_raw", "smart_223_raw", "smart_3_raw", "smart_11_raw", "smart_191_raw"],
+"svm_114.pkl":["smart_226_raw", "smart_188_raw", "smart_2_raw", "smart_11_raw", "smart_4_raw", "smart_193_raw", "smart_184_raw", "smart_194_raw", "smart_198_raw", "smart_13_raw"],
+"svm_219.pkl":["smart_12_raw", "smart_22_raw", "smart_8_raw", "smart_191_raw", "smart_197_raw", "smart_254_raw", "smart_15_raw", "smart_193_raw", "smart_199_raw", "smart_225_raw", "smart_192_raw"],
+"svm_168.pkl":["smart_255_raw", "smart_191_raw", "smart_193_raw", "smart_220_raw", "smart_5_raw", "smart_3_raw", "smart_222_raw", "smart_223_raw", "smart_197_raw", "smart_196_raw", "smart_22_raw"],
+"svm_243.pkl":["smart_11_raw", "smart_255_raw", "smart_10_raw", "smart_189_raw", "smart_225_raw", "smart_240_raw", "smart_222_raw", "smart_197_raw", "smart_183_raw", "smart_198_raw", "smart_12_raw"],
+"svm_195.pkl":["smart_183_raw", "smart_5_raw", "smart_11_raw", "smart_197_raw", "smart_15_raw", "smart_9_raw", "smart_4_raw", "smart_220_raw", "smart_12_raw", "smart_192_raw", "smart_240_raw"],
+"svm_222.pkl":["smart_10_raw", "smart_13_raw", "smart_188_raw", "smart_15_raw", "smart_192_raw", "smart_224_raw", "smart_225_raw", "smart_187_raw", "smart_222_raw", "smart_220_raw", "smart_252_raw"],
+"svm_62.pkl":["smart_196_raw", "smart_251_raw", "smart_187_raw", "smart_224_raw", "smart_11_raw", "smart_12_raw", "smart_8_raw", "smart_199_raw", "smart_220_raw", "smart_195_raw"],
+"svm_151.pkl":["smart_187_raw", "smart_223_raw", "smart_200_raw", "smart_189_raw", "smart_251_raw", "smart_255_raw", "smart_222_raw", "smart_192_raw", "smart_12_raw", "smart_183_raw", "smart_22_raw"],
+"svm_125.pkl":["smart_9_raw", "smart_252_raw", "smart_197_raw", "smart_251_raw", "smart_11_raw", "smart_12_raw", "smart_188_raw", "smart_240_raw", "smart_10_raw", "smart_223_raw"],
+"svm_124.pkl":["smart_193_raw", "smart_187_raw", "smart_183_raw", "smart_11_raw", "smart_10_raw", "smart_8_raw", "smart_194_raw", "smart_189_raw", "smart_222_raw", "smart_191_raw"],
+"svm_67.pkl":["smart_2_raw", "smart_8_raw", "smart_225_raw", "smart_240_raw", "smart_13_raw", "smart_5_raw", "smart_187_raw", "smart_198_raw", "smart_199_raw", "smart_3_raw"],
+"svm_115.pkl":["smart_222_raw", "smart_193_raw", "smart_223_raw", "smart_195_raw", "smart_252_raw", "smart_189_raw", "smart_199_raw", "smart_187_raw", "smart_15_raw", "smart_184_raw"],
+"svm_1.pkl":["smart_201_raw", "smart_8_raw", "smart_200_raw", "smart_252_raw", "smart_251_raw", "smart_187_raw", "smart_9_raw", "smart_188_raw", "smart_15_raw", "smart_184_raw"],
+"svm_112.pkl":["smart_220_raw", "smart_197_raw", "smart_10_raw", "smart_188_raw", "smart_12_raw", "smart_4_raw", "smart_196_raw", "smart_3_raw", "smart_240_raw", "smart_225_raw"],
+"svm_138.pkl":["smart_183_raw", "smart_10_raw", "smart_191_raw", "smart_195_raw", "smart_223_raw", "smart_189_raw", "smart_187_raw", "smart_255_raw", "smart_226_raw", "smart_8_raw"],
+"svm_229.pkl":["smart_224_raw", "smart_8_raw", "smart_192_raw", "smart_220_raw", "smart_195_raw", "smart_183_raw", "smart_250_raw", "smart_187_raw", "smart_225_raw", "smart_4_raw", "smart_252_raw"],
+"svm_145.pkl":["smart_190_raw", "smart_8_raw", "smart_226_raw", "smart_184_raw", "smart_225_raw", "smart_220_raw", "smart_193_raw", "smart_183_raw", "smart_201_raw", "smart_187_raw", "smart_2_raw"],
+"svm_59.pkl":["smart_188_raw", "smart_11_raw", "smart_184_raw", "smart_2_raw", "smart_220_raw", "smart_198_raw", "smart_225_raw", "smart_240_raw", "smart_197_raw", "smart_251_raw"],
+"svm_204.pkl":["smart_15_raw", "smart_240_raw", "smart_225_raw", "smart_223_raw", "smart_252_raw", "smart_22_raw", "smart_200_raw", "smart_13_raw", "smart_220_raw", "smart_198_raw", "smart_191_raw"],
+"svm_88.pkl":["smart_198_raw", "smart_3_raw", "smart_8_raw", "smart_225_raw", "smart_251_raw", "smart_222_raw", "smart_188_raw", "smart_10_raw", "smart_240_raw", "smart_189_raw"],
+"svm_182.pkl":["smart_10_raw", "smart_190_raw", "smart_250_raw", "smart_15_raw", "smart_193_raw", "smart_22_raw", "smart_200_raw", "smart_8_raw", "smart_4_raw", "smart_187_raw", "smart_9_raw"],
+"svm_61.pkl":["smart_5_raw", "smart_12_raw", "smart_9_raw", "smart_198_raw", "smart_195_raw", "smart_252_raw", "smart_15_raw", "smart_240_raw", "smart_255_raw", "smart_224_raw"],
+"svm_50.pkl":["smart_220_raw", "smart_5_raw", "smart_194_raw", "smart_250_raw", "smart_15_raw", "smart_240_raw", "smart_8_raw", "smart_198_raw", "smart_224_raw", "smart_191_raw"],
+"svm_210.pkl":["smart_8_raw", "smart_15_raw", "smart_195_raw", "smart_224_raw", "smart_5_raw", "smart_191_raw", "smart_198_raw", "smart_225_raw", "smart_200_raw", "smart_251_raw", "smart_240_raw"],
+"svm_16.pkl":["smart_222_raw", "smart_10_raw", "smart_250_raw", "smart_189_raw", "smart_191_raw", "smart_2_raw", "smart_5_raw", "smart_193_raw", "smart_9_raw", "smart_187_raw"],
+"svm_85.pkl":["smart_252_raw", "smart_184_raw", "smart_9_raw", "smart_5_raw", "smart_254_raw", "smart_3_raw", "smart_195_raw", "smart_10_raw", "smart_12_raw", "smart_222_raw"],
+"svm_36.pkl":["smart_201_raw", "smart_251_raw", "smart_184_raw", "smart_3_raw", "smart_5_raw", "smart_183_raw", "smart_194_raw", "smart_195_raw", "smart_224_raw", "smart_2_raw"],
+"svm_33.pkl":["smart_223_raw", "smart_254_raw", "smart_225_raw", "smart_9_raw", "smart_199_raw", "smart_5_raw", "smart_189_raw", "smart_194_raw", "smart_240_raw", "smart_4_raw"],
+"svm_3.pkl":["smart_225_raw", "smart_194_raw", "smart_3_raw", "smart_189_raw", "smart_9_raw", "smart_254_raw", "smart_240_raw", "smart_5_raw", "smart_255_raw", "smart_223_raw"],
+"svm_93.pkl":["smart_8_raw", "smart_188_raw", "smart_5_raw", "smart_10_raw", "smart_222_raw", "smart_2_raw", "smart_254_raw", "smart_12_raw", "smart_193_raw", "smart_224_raw"],
+"svm_120.pkl":["smart_189_raw", "smart_224_raw", "smart_222_raw", "smart_193_raw", "smart_5_raw", "smart_201_raw", "smart_8_raw", "smart_254_raw", "smart_194_raw", "smart_22_raw"],
+"svm_128.pkl":["smart_195_raw", "smart_184_raw", "smart_251_raw", "smart_8_raw", "smart_5_raw", "smart_196_raw", "smart_10_raw", "smart_4_raw", "smart_225_raw", "smart_191_raw"],
+"svm_212.pkl":["smart_225_raw", "smart_192_raw", "smart_10_raw", "smart_12_raw", "smart_222_raw", "smart_184_raw", "smart_13_raw", "smart_226_raw", "smart_5_raw", "smart_201_raw", "smart_22_raw"],
+"svm_221.pkl":["smart_255_raw", "smart_2_raw", "smart_224_raw", "smart_192_raw", "smart_252_raw", "smart_13_raw", "smart_183_raw", "smart_193_raw", "smart_15_raw", "smart_199_raw", "smart_200_raw"],
+"svm_223.pkl":["smart_4_raw", "smart_194_raw", "smart_9_raw", "smart_255_raw", "smart_188_raw", "smart_201_raw", "smart_3_raw", "smart_226_raw", "smart_192_raw", "smart_251_raw", "smart_191_raw"],
+"svm_44.pkl":["smart_255_raw", "smart_11_raw", "smart_200_raw", "smart_3_raw", "smart_195_raw", "smart_201_raw", "smart_4_raw", "smart_5_raw", "smart_10_raw", "smart_191_raw"],
+"svm_213.pkl":["smart_22_raw", "smart_191_raw", "smart_183_raw", "smart_4_raw", "smart_194_raw", "smart_255_raw", "smart_254_raw", "smart_193_raw", "smart_11_raw", "smart_10_raw", "smart_220_raw"],
+"svm_131.pkl":["smart_22_raw", "smart_194_raw", "smart_184_raw", "smart_250_raw", "smart_10_raw", "smart_189_raw", "smart_183_raw", "smart_240_raw", "smart_12_raw", "smart_252_raw"],
+"svm_6.pkl":["smart_194_raw", "smart_250_raw", "smart_223_raw", "smart_224_raw", "smart_184_raw", "smart_191_raw", "smart_201_raw", "smart_9_raw", "smart_252_raw", "smart_3_raw"],
+"svm_161.pkl":["smart_255_raw", "smart_222_raw", "smart_226_raw", "smart_254_raw", "smart_183_raw", "smart_22_raw", "smart_12_raw", "smart_190_raw", "smart_11_raw", "smart_192_raw", "smart_251_raw"],
+"svm_72.pkl":["smart_13_raw", "smart_184_raw", "smart_223_raw", "smart_240_raw", "smart_250_raw", "smart_251_raw", "smart_201_raw", "smart_196_raw", "smart_5_raw", "smart_4_raw"],
+"svm_27.pkl":["smart_189_raw", "smart_188_raw", "smart_255_raw", "smart_251_raw", "smart_240_raw", "smart_15_raw", "smart_9_raw", "smart_191_raw", "smart_226_raw", "smart_10_raw"],
+"svm_141.pkl":["smart_9_raw", "smart_191_raw", "smart_2_raw", "smart_226_raw", "smart_13_raw", "smart_22_raw", "smart_193_raw", "smart_222_raw", "smart_220_raw", "smart_225_raw", "smart_3_raw"],
+"svm_57.pkl":["smart_12_raw", "smart_252_raw", "smart_190_raw", "smart_226_raw", "smart_10_raw", "smart_189_raw", "smart_193_raw", "smart_2_raw", "smart_9_raw", "smart_223_raw"],
+"svm_236.pkl":["smart_200_raw", "smart_189_raw", "smart_226_raw", "smart_252_raw", "smart_250_raw", "smart_193_raw", "smart_13_raw", "smart_2_raw", "smart_254_raw", "smart_22_raw", "smart_9_raww"],
+"svm_208.pkl":["smart_223_raw", "smart_15_raw", "smart_251_raw", "smart_5_raw", "smart_198_raw", "smart_252_raw", "smart_4_raw", "smart_8_raw", "smart_220_raw", "smart_254_raw", "smart_193_raw"],
+"svm_230.pkl":["smart_184_raw", "smart_5_raw", "smart_191_raw", "smart_198_raw", "smart_11_raw", "smart_255_raw", "smart_189_raw", "smart_254_raw", "smart_196_raw", "smart_199_raw", "smart_223_raw"],
+"svm_134.pkl":["smart_8_raw", "smart_194_raw", "smart_4_raw", "smart_189_raw", "smart_223_raw", "smart_5_raw", "smart_187_raw", "smart_9_raw", "smart_192_raw", "smart_220_raw"],
+"svm_71.pkl":["smart_220_raw", "smart_13_raw", "smart_194_raw", "smart_197_raw", "smart_192_raw", "smart_22_raw", "smart_184_raw", "smart_199_raw", "smart_222_raw", "smart_183_raw"],
+"svm_109.pkl":["smart_224_raw", "smart_252_raw", "smart_2_raw", "smart_200_raw", "smart_5_raw", "smart_194_raw", "smart_222_raw", "smart_198_raw", "smart_4_raw", "smart_13_raw"]
+}
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_1.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_1.pkl
new file mode 100644
index 000000000..5eb30f300
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_1.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_10.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_10.pkl
new file mode 100644
index 000000000..9259c1e74
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_10.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_104.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_104.pkl
new file mode 100644
index 000000000..d5d5cf5b7
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_104.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_105.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_105.pkl
new file mode 100644
index 000000000..4aadc3cfb
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_105.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_109.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_109.pkl
new file mode 100644
index 000000000..c99c353be
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_109.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_112.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_112.pkl
new file mode 100644
index 000000000..367a3304a
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_112.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_114.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_114.pkl
new file mode 100644
index 000000000..946d5cef1
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_114.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_115.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_115.pkl
new file mode 100644
index 000000000..ff834929e
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_115.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_118.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_118.pkl
new file mode 100644
index 000000000..eec8689ea
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_118.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_119.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_119.pkl
new file mode 100644
index 000000000..6a26c0502
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_119.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_12.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_12.pkl
new file mode 100644
index 000000000..5cbe9775a
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_12.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_120.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_120.pkl
new file mode 100644
index 000000000..d2041c267
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_120.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_123.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_123.pkl
new file mode 100644
index 000000000..0ab6187e9
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_123.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_124.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_124.pkl
new file mode 100644
index 000000000..8f9ea4ec7
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_124.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_125.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_125.pkl
new file mode 100644
index 000000000..4d49900f9
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_125.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_128.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_128.pkl
new file mode 100644
index 000000000..6a18726de
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_128.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_131.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_131.pkl
new file mode 100644
index 000000000..e6a55dcae
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_131.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_134.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_134.pkl
new file mode 100644
index 000000000..51171e00c
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_134.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_138.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_138.pkl
new file mode 100644
index 000000000..bc98e0c72
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_138.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_14.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_14.pkl
new file mode 100644
index 000000000..c4547dc63
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_14.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_141.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_141.pkl
new file mode 100644
index 000000000..86d9f38de
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_141.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_145.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_145.pkl
new file mode 100644
index 000000000..24ff96231
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_145.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_151.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_151.pkl
new file mode 100644
index 000000000..92bfd3f1b
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_151.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_16.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_16.pkl
new file mode 100644
index 000000000..11664b3dd
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_16.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_161.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_161.pkl
new file mode 100644
index 000000000..2d421685e
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_161.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_168.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_168.pkl
new file mode 100644
index 000000000..12a811cfa
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_168.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_169.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_169.pkl
new file mode 100644
index 000000000..0c51446c6
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_169.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_174.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_174.pkl
new file mode 100644
index 000000000..d2945ce9f
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_174.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_18.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_18.pkl
new file mode 100644
index 000000000..d05520ccd
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_18.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_182.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_182.pkl
new file mode 100644
index 000000000..7fcfb3cbd
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_182.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_185.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_185.pkl
new file mode 100644
index 000000000..785301c17
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_185.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_186.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_186.pkl
new file mode 100644
index 000000000..4ea83da77
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_186.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_195.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_195.pkl
new file mode 100644
index 000000000..12273f7ce
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_195.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_201.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_201.pkl
new file mode 100644
index 000000000..c866cf00e
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_201.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_204.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_204.pkl
new file mode 100644
index 000000000..8cf1c3aa2
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_204.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_206.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_206.pkl
new file mode 100644
index 000000000..cba64e800
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_206.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_208.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_208.pkl
new file mode 100644
index 000000000..ba0df0abd
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_208.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_210.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_210.pkl
new file mode 100644
index 000000000..6b5bee219
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_210.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_212.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_212.pkl
new file mode 100644
index 000000000..11eafc64c
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_212.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_213.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_213.pkl
new file mode 100644
index 000000000..0b8475c58
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_213.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_219.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_219.pkl
new file mode 100644
index 000000000..4a248c14c
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_219.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_221.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_221.pkl
new file mode 100644
index 000000000..e37c6b4fb
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_221.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_222.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_222.pkl
new file mode 100644
index 000000000..e54303863
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_222.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_223.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_223.pkl
new file mode 100644
index 000000000..8b208f4e8
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_223.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_225.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_225.pkl
new file mode 100644
index 000000000..3f2b62984
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_225.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_227.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_227.pkl
new file mode 100644
index 000000000..5e4fb56f4
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_227.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_229.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_229.pkl
new file mode 100644
index 000000000..1e9c33599
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_229.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_230.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_230.pkl
new file mode 100644
index 000000000..36f8205ce
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_230.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_234.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_234.pkl
new file mode 100644
index 000000000..199f9ba51
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_234.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_235.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_235.pkl
new file mode 100644
index 000000000..d986526ec
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_235.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_236.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_236.pkl
new file mode 100644
index 000000000..160e22fae
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_236.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_239.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_239.pkl
new file mode 100644
index 000000000..8d98572ac
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_239.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_243.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_243.pkl
new file mode 100644
index 000000000..4fca95e1d
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_243.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_27.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_27.pkl
new file mode 100644
index 000000000..011974ed1
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_27.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_3.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_3.pkl
new file mode 100644
index 000000000..e5e97a888
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_3.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_33.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_33.pkl
new file mode 100644
index 000000000..e709d7b46
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_33.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_36.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_36.pkl
new file mode 100644
index 000000000..3d87b8bd9
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_36.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_44.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_44.pkl
new file mode 100644
index 000000000..9abcece92
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_44.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_50.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_50.pkl
new file mode 100644
index 000000000..b7ce5eda9
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_50.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_57.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_57.pkl
new file mode 100644
index 000000000..fe7832894
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_57.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_59.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_59.pkl
new file mode 100644
index 000000000..76217777b
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_59.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_6.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_6.pkl
new file mode 100644
index 000000000..4fb09d374
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_6.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_61.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_61.pkl
new file mode 100644
index 000000000..319fc5f45
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_61.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_62.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_62.pkl
new file mode 100644
index 000000000..25b21aed6
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_62.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_67.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_67.pkl
new file mode 100644
index 000000000..1e6e7383a
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_67.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_69.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_69.pkl
new file mode 100644
index 000000000..22d349a7c
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_69.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_71.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_71.pkl
new file mode 100644
index 000000000..e0760add9
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_71.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_72.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_72.pkl
new file mode 100644
index 000000000..5096aa8e4
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_72.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_78.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_78.pkl
new file mode 100644
index 000000000..7958f3b6c
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_78.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_79.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_79.pkl
new file mode 100644
index 000000000..2ed3a0fe9
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_79.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_82.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_82.pkl
new file mode 100644
index 000000000..2e1884094
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_82.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_85.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_85.pkl
new file mode 100644
index 000000000..88161af56
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_85.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_88.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_88.pkl
new file mode 100644
index 000000000..715633982
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_88.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_93.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_93.pkl
new file mode 100644
index 000000000..703429fe3
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_93.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_97.pkl b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_97.pkl
new file mode 100644
index 000000000..9653d20f3
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/prophetstor/svm_97.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/redhat/config.json b/src/pybind/mgr/diskprediction_local/models/redhat/config.json
new file mode 100644
index 000000000..62a0d8282
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/redhat/config.json
@@ -0,0 +1,4 @@
+{
+"seagate": ["user_capacity", "smart_1_raw", "smart_5_raw", "smart_7_raw", "smart_10_raw", "smart_187_raw", "smart_188_raw", "smart_190_raw", "smart_193_raw", "smart_197_raw", "smart_198_raw", "smart_241_raw", "smart_1_normalized", "smart_5_normalized", "smart_7_normalized", "smart_10_normalized", "smart_187_normalized", "smart_188_normalized", "smart_190_normalized", "smart_193_normalized", "smart_197_normalized", "smart_198_normalized", "smart_241_normalized"],
+"hgst": ["user_capacity", "smart_1_normalized", "smart_1_raw", "smart_2_normalized", "smart_2_raw", "smart_3_normalized", "smart_3_raw", "smart_4_raw", "smart_5_normalized", "smart_5_raw", "smart_7_normalized", "smart_7_raw", "smart_8_normalized", "smart_8_raw", "smart_9_normalized", "smart_9_raw", "smart_10_normalized", "smart_10_raw", "smart_12_raw", "smart_192_normalized", "smart_192_raw", "smart_193_normalized", "smart_193_raw", "smart_194_normalized", "smart_194_raw", "smart_196_normalized", "smart_196_raw", "smart_197_normalized", "smart_197_raw", "smart_198_raw", "smart_199_raw"]
+}
diff --git a/src/pybind/mgr/diskprediction_local/models/redhat/hgst_predictor.pkl b/src/pybind/mgr/diskprediction_local/models/redhat/hgst_predictor.pkl
new file mode 100644
index 000000000..9894d9f55
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/redhat/hgst_predictor.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/redhat/hgst_scaler.pkl b/src/pybind/mgr/diskprediction_local/models/redhat/hgst_scaler.pkl
new file mode 100644
index 000000000..6f77b85cc
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/redhat/hgst_scaler.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/redhat/seagate_predictor.pkl b/src/pybind/mgr/diskprediction_local/models/redhat/seagate_predictor.pkl
new file mode 100644
index 000000000..280d59a08
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/redhat/seagate_predictor.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/models/redhat/seagate_scaler.pkl b/src/pybind/mgr/diskprediction_local/models/redhat/seagate_scaler.pkl
new file mode 100644
index 000000000..691bb03c5
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/models/redhat/seagate_scaler.pkl
Binary files differ
diff --git a/src/pybind/mgr/diskprediction_local/module.py b/src/pybind/mgr/diskprediction_local/module.py
new file mode 100644
index 000000000..450dc9c83
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/module.py
@@ -0,0 +1,305 @@
+"""
+diskprediction with local predictor
+"""
+import json
+import datetime
+from threading import Event
+import time
+from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING
+from mgr_module import CommandResult, MgrModule, Option
+# Importing scipy early appears to avoid a future deadlock when
+# we try to do
+#
+# from .predictor import get_diskfailurepredictor_path
+#
+# in a command thread. See https://tracker.ceph.com/issues/42764
+import scipy # noqa: ignore=F401
+from .predictor import DevSmartT, Predictor, get_diskfailurepredictor_path
+
+
+TIME_FORMAT = '%Y%m%d-%H%M%S'
+TIME_DAYS = 24 * 60 * 60
+TIME_WEEK = TIME_DAYS * 7
+
+
+class Module(MgrModule):
+ MODULE_OPTIONS = [
+ Option(name='sleep_interval',
+ default=600),
+ Option(name='predict_interval',
+ default=86400),
+ Option(name='predictor_model',
+ default='prophetstor')
+ ]
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ super(Module, self).__init__(*args, **kwargs)
+ # options
+ for opt in self.MODULE_OPTIONS:
+ setattr(self, opt['name'], opt['default'])
+ # other
+ self._run = True
+ self._event = Event()
+ # for mypy which does not run the code
+ if TYPE_CHECKING:
+ self.sleep_interval = 0
+ self.predict_interval = 0
+ self.predictor_model = ''
+
+ def config_notify(self) -> None:
+ for opt in self.MODULE_OPTIONS:
+ setattr(self,
+ opt['name'],
+ self.get_module_option(opt['name']))
+ self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name']))
+ if self.get_ceph_option('device_failure_prediction_mode') == 'local':
+ self._event.set()
+
+ def refresh_config(self) -> None:
+ for opt in self.MODULE_OPTIONS:
+ setattr(self,
+ opt['name'],
+ self.get_module_option(opt['name']))
+ self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name']))
+
+ def self_test(self) -> None:
+ self.log.debug('self_test enter')
+ ret, out, err = self.predict_all_devices()
+ assert ret == 0
+
+ def serve(self) -> None:
+ self.log.info('Starting diskprediction local module')
+ self.config_notify()
+ last_predicted = None
+ ls = self.get_store('last_predicted')
+ if ls:
+ try:
+ last_predicted = datetime.datetime.strptime(ls, TIME_FORMAT)
+ except ValueError:
+ pass
+ self.log.debug('Last predicted %s', last_predicted)
+
+ while self._run:
+ self.refresh_config()
+ mode = self.get_ceph_option('device_failure_prediction_mode')
+ if mode == 'local':
+ now = datetime.datetime.utcnow()
+ if not last_predicted:
+ next_predicted = now
+ else:
+ predicted_frequency = self.predict_interval or 86400
+ seconds = (last_predicted - datetime.datetime.utcfromtimestamp(0)).total_seconds()
+ seconds -= seconds % predicted_frequency
+ seconds += predicted_frequency
+ next_predicted = datetime.datetime.utcfromtimestamp(seconds)
+ self.log.debug('Last scrape %s, next scrape due %s',
+ last_predicted.strftime(TIME_FORMAT),
+ next_predicted.strftime(TIME_FORMAT))
+ if now >= next_predicted:
+ self.predict_all_devices()
+ last_predicted = now
+ self.set_store('last_predicted', last_predicted.strftime(TIME_FORMAT))
+
+ sleep_interval = self.sleep_interval or 60
+ self.log.debug('Sleeping for %d seconds', sleep_interval)
+ self._event.wait(sleep_interval)
+ self._event.clear()
+
+ def shutdown(self) -> None:
+ self.log.info('Stopping')
+ self._run = False
+ self._event.set()
+
+ @staticmethod
+ def _convert_timestamp(predicted_timestamp: int, life_expectancy_day: int) -> str:
+ """
+ :param predicted_timestamp: unit is nanoseconds
+ :param life_expectancy_day: unit is seconds
+ :return:
+ date format '%Y-%m-%d' ex. 2018-01-01
+ """
+ return datetime.datetime.fromtimestamp(
+ predicted_timestamp / (1000 ** 3) + life_expectancy_day).strftime('%Y-%m-%d')
+
+ def _predict_life_expectancy(self, devid: str) -> str:
+ predicted_result = ''
+ health_data: Dict[str, Dict[str, Any]] = {}
+ predict_datas: List[DevSmartT] = []
+ try:
+ r, outb, outs = self.remote(
+ 'devicehealth', 'show_device_metrics', devid=devid, sample='')
+ if r != 0:
+ self.log.error('failed to get device %s health', devid)
+ health_data = {}
+ else:
+ health_data = json.loads(outb)
+ except Exception as e:
+ self.log.error('failed to get device %s health data due to %s', devid, str(e))
+
+ # initialize appropriate disk failure predictor model
+ obj_predictor = Predictor.create(self.predictor_model)
+ if obj_predictor is None:
+ self.log.error('invalid value received for MODULE_OPTIONS.predictor_model')
+ return predicted_result
+ try:
+ obj_predictor.initialize(
+ "{}/models/{}".format(get_diskfailurepredictor_path(), self.predictor_model))
+ except Exception as e:
+ self.log.error('Error initializing predictor: %s', e)
+ return predicted_result
+
+ if len(health_data) >= 6:
+ o_keys = sorted(health_data.keys(), reverse=True)
+ for o_key in o_keys:
+ # get values for current day (?)
+ dev_smart = {}
+ s_val = health_data[o_key]
+
+ # add all smart attributes
+ ata_smart = s_val.get('ata_smart_attributes', {})
+ for attr in ata_smart.get('table', []):
+ # get raw smart values
+ if attr.get('raw', {}).get('string') is not None:
+ if str(attr.get('raw', {}).get('string', '0')).isdigit():
+ dev_smart['smart_%s_raw' % attr.get('id')] = \
+ int(attr.get('raw', {}).get('string', '0'))
+ else:
+ if str(attr.get('raw', {}).get('string', '0')).split(' ')[0].isdigit():
+ dev_smart['smart_%s_raw' % attr.get('id')] = \
+ int(attr.get('raw', {}).get('string',
+ '0').split(' ')[0])
+ else:
+ dev_smart['smart_%s_raw' % attr.get('id')] = \
+ attr.get('raw', {}).get('value', 0)
+ # get normalized smart values
+ if attr.get('value') is not None:
+ dev_smart['smart_%s_normalized' % attr.get('id')] = \
+ attr.get('value')
+ # add power on hours manually if not available in smart attributes
+ power_on_time = s_val.get('power_on_time', {}).get('hours')
+ if power_on_time is not None:
+ dev_smart['smart_9_raw'] = int(power_on_time)
+ # add device capacity
+ user_capacity = s_val.get('user_capacity', {}).get('bytes')
+ if user_capacity is not None:
+ dev_smart['user_capacity'] = user_capacity
+ else:
+ self.log.debug('user_capacity not found in smart attributes list')
+ # add device model
+ model_name = s_val.get('model_name')
+ if model_name is not None:
+ dev_smart['model_name'] = model_name
+ # add vendor
+ vendor = s_val.get('vendor')
+ if vendor is not None:
+ dev_smart['vendor'] = vendor
+ # if smart data was found, then add that to list
+ if dev_smart:
+ predict_datas.append(dev_smart)
+ if len(predict_datas) >= 12:
+ break
+ else:
+ self.log.error('unable to predict device due to health data records less than 6 days')
+
+ if len(predict_datas) >= 6:
+ predicted_result = obj_predictor.predict(predict_datas)
+ return predicted_result
+
+ def predict_life_expectancy(self, devid: str) -> Tuple[int, str, str]:
+ result = self._predict_life_expectancy(devid)
+ if result.lower() == 'good':
+ return 0, '>6w', ''
+ elif result.lower() == 'warning':
+ return 0, '>=2w and <=6w', ''
+ elif result.lower() == 'bad':
+ return 0, '<2w', ''
+ else:
+ return 0, 'unknown', ''
+
+ def _reset_device_life_expectancy(self, device_id: str) -> int:
+ result = CommandResult('')
+ self.send_command(result, 'mon', '', json.dumps({
+ 'prefix': 'device rm-life-expectancy',
+ 'devid': device_id
+ }), '')
+ ret, _, outs = result.wait()
+ if ret != 0:
+ self.log.error(
+ 'failed to reset device life expectancy, %s' % outs)
+ return ret
+
+ def _set_device_life_expectancy(self,
+ device_id: str,
+ from_date: str,
+ to_date: Optional[str] = None) -> int:
+ result = CommandResult('')
+
+ if to_date is None:
+ self.send_command(result, 'mon', '', json.dumps({
+ 'prefix': 'device set-life-expectancy',
+ 'devid': device_id,
+ 'from': from_date
+ }), '')
+ else:
+ self.send_command(result, 'mon', '', json.dumps({
+ 'prefix': 'device set-life-expectancy',
+ 'devid': device_id,
+ 'from': from_date,
+ 'to': to_date
+ }), '')
+ ret, _, outs = result.wait()
+ if ret != 0:
+ self.log.error(
+ 'failed to set device life expectancy, %s' % outs)
+ return ret
+
+ def predict_all_devices(self) -> Tuple[int, str, str]:
+ self.log.debug('predict_all_devices')
+ devices = self.get('devices').get('devices', [])
+ for devInfo in devices:
+ if not devInfo.get('daemons'):
+ continue
+ if not devInfo.get('devid'):
+ continue
+ self.log.debug('%s' % devInfo)
+ result = self._predict_life_expectancy(devInfo['devid'])
+ if result == 'unknown':
+ self._reset_device_life_expectancy(devInfo['devid'])
+ continue
+ predicted = int(time.time() * (1000 ** 3))
+
+ if result.lower() == 'good':
+ life_expectancy_day_min = (TIME_WEEK * 6) + TIME_DAYS
+ life_expectancy_day_max = 0
+ elif result.lower() == 'warning':
+ life_expectancy_day_min = (TIME_WEEK * 2)
+ life_expectancy_day_max = (TIME_WEEK * 6)
+ elif result.lower() == 'bad':
+ life_expectancy_day_min = 0
+ life_expectancy_day_max = (TIME_WEEK * 2) - TIME_DAYS
+ else:
+ predicted = 0
+ life_expectancy_day_min = 0
+ life_expectancy_day_max = 0
+
+ if predicted and devInfo['devid'] and life_expectancy_day_min:
+ from_date = None
+ to_date = None
+ try:
+ assert life_expectancy_day_min
+ from_date = self._convert_timestamp(predicted, life_expectancy_day_min)
+
+ if life_expectancy_day_max:
+ to_date = self._convert_timestamp(predicted, life_expectancy_day_max)
+
+ self._set_device_life_expectancy(devInfo['devid'], from_date, to_date)
+ self._logger.info(
+ 'succeed to set device {} life expectancy from: {}, to: {}'.format(
+ devInfo['devid'], from_date, to_date))
+ except Exception as e:
+ self._logger.error(
+ 'failed to set device {} life expectancy from: {}, to: {}, {}'.format(
+ devInfo['devid'], from_date, to_date, str(e)))
+ else:
+ self._reset_device_life_expectancy(devInfo['devid'])
+ return 0, 'succeed to predicted all devices', ''
diff --git a/src/pybind/mgr/diskprediction_local/predictor.py b/src/pybind/mgr/diskprediction_local/predictor.py
new file mode 100644
index 000000000..3bbe7a4b7
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/predictor.py
@@ -0,0 +1,484 @@
+"""Machine learning model for disk failure prediction.
+
+This classes defined here provide the disk failure prediction module.
+RHDiskFailurePredictor uses the models developed at the AICoE in the
+Office of the CTO at Red Hat. These models were built using the open
+source Backblaze SMART metrics dataset.
+PSDiskFailurePredictor uses the models developed by ProphetStor as an
+example.
+
+An instance of the predictor is initialized by providing the path to trained
+models. Then, to predict hard drive health and deduce time to failure, the
+predict function is called with 6 days worth of SMART data from the hard drive.
+It will return a string to indicate disk failure status: "Good", "Warning",
+"Bad", or "Unknown".
+
+An example code is as follows:
+
+>>> model = RHDiskFailurePredictor()
+>>> model.initialize(get_diskfailurepredictor_path() + "/models/redhat")
+>>> vendor = list(RHDiskFailurePredictor.MANUFACTURER_MODELNAME_PREFIXES.keys())[0]
+>>> disk_days = [{'vendor': vendor}]
+>>> model.predict(disk_days)
+'Unknown'
+"""
+import os
+import json
+import pickle
+import logging
+from typing import Any, Dict, List, Optional, Sequence, Tuple
+
+import numpy as np
+
+
+def get_diskfailurepredictor_path() -> str:
+ path = os.path.abspath(__file__)
+ dir_path = os.path.dirname(path)
+ return dir_path
+
+
+DevSmartT = Dict[str, Any]
+AttrNamesT = List[str]
+AttrDiffsT = List[Dict[str, int]]
+
+
+class Predictor:
+ @classmethod
+ def create(cls, name: str) -> Optional['Predictor']:
+ if name == 'prophetstor':
+ return PSDiskFailurePredictor()
+ elif name == 'redhat':
+ return RHDiskFailurePredictor()
+ else:
+ return None
+
+ def initialize(self, model_dir: str) -> None:
+ raise NotImplementedError()
+
+ def predict(self, dataset: Sequence[DevSmartT]) -> str:
+ raise NotImplementedError()
+
+
+class RHDiskFailurePredictor(Predictor):
+ """Disk failure prediction module developed at Red Hat
+
+ This class implements a disk failure prediction module.
+ """
+
+ # json with manufacturer names as keys
+ # and features used for prediction as values
+ CONFIG_FILE = "config.json"
+ PREDICTION_CLASSES = {-1: "Unknown", 0: "Good", 1: "Warning", 2: "Bad"}
+
+ # model name prefixes to identify vendor
+ MANUFACTURER_MODELNAME_PREFIXES = {
+ "WDC": "WDC",
+ "Toshiba": "Toshiba", # for cases like "Toshiba xxx"
+ "TOSHIBA": "Toshiba", # for cases like "TOSHIBA xxx"
+ "toshiba": "Toshiba", # for cases like "toshiba xxx"
+ "S": "Seagate", # for cases like "STxxxx" and "Seagate BarraCuda ZAxxx"
+ "ZA": "Seagate", # for cases like "ZAxxxx"
+ "Hitachi": "Hitachi",
+ "HGST": "HGST",
+ }
+
+ LOGGER = logging.getLogger()
+
+ def __init__(self) -> None:
+ """
+ This function may throw exception due to wrong file operation.
+ """
+ self.model_dirpath = ""
+ self.model_context: Dict[str, List[str]] = {}
+
+ def initialize(self, model_dirpath: str) -> None:
+ """Initialize all models. Save paths of all trained model files to list
+
+ Arguments:
+ model_dirpath {str} -- path to directory of trained models
+
+ Returns:
+ str -- Error message. If all goes well, return None
+ """
+ # read config file as json, if it exists
+ config_path = os.path.join(model_dirpath, self.CONFIG_FILE)
+ if not os.path.isfile(config_path):
+ raise Exception("Missing config file: " + config_path)
+ with open(config_path) as f_conf:
+ self.model_context = json.load(f_conf)
+
+ # ensure all manufacturers whose context is defined in config file
+ # have models and scalers saved inside model_dirpath
+ for manufacturer in self.model_context:
+ scaler_path = os.path.join(model_dirpath, manufacturer + "_scaler.pkl")
+ if not os.path.isfile(scaler_path):
+ raise Exception(f"Missing scaler file: {scaler_path}")
+ model_path = os.path.join(model_dirpath, manufacturer + "_predictor.pkl")
+ if not os.path.isfile(model_path):
+ raise Exception(f"Missing model file: {model_path}")
+
+ self.model_dirpath = model_dirpath
+
+ def __preprocess(self, disk_days: Sequence[DevSmartT], manufacturer: str) -> Optional[np.ndarray]:
+ """Scales and transforms input dataframe to feed it to prediction model
+
+ Arguments:
+ disk_days {list} -- list in which each element is a dictionary with key,val
+ as feature name,value respectively.
+ e.g.[{'smart_1_raw': 0, 'user_capacity': 512 ...}, ...]
+ manufacturer {str} -- manufacturer of the hard drive
+
+ Returns:
+ numpy.ndarray -- (n, d) shaped array of n days worth of data and d
+ features, scaled
+ """
+ # get the attributes that were used to train model for current manufacturer
+ try:
+ model_smart_attr = self.model_context[manufacturer]
+ except KeyError:
+ RHDiskFailurePredictor.LOGGER.debug(
+ "No context (SMART attributes on which model has been trained) found for manufacturer: {}".format(
+ manufacturer
+ )
+ )
+ return None
+
+ # convert to structured array, keeping only the required features
+ # assumes all data is in float64 dtype
+ try:
+ struc_dtypes = [(attr, np.float64) for attr in model_smart_attr]
+ values = [tuple(day[attr] for attr in model_smart_attr) for day in disk_days]
+ disk_days_sa = np.array(values, dtype=struc_dtypes)
+ except KeyError:
+ RHDiskFailurePredictor.LOGGER.debug(
+ "Mismatch in SMART attributes used to train model and SMART attributes available"
+ )
+ return None
+
+ # view structured array as 2d array for applying rolling window transforms
+ # do not include capacity_bytes in this. only use smart_attrs
+ disk_days_attrs = disk_days_sa[[attr for attr in model_smart_attr if 'smart_' in attr]]\
+ .view(np.float64).reshape(disk_days_sa.shape + (-1,))
+
+ # featurize n (6 to 12) days data - mean,std,coefficient of variation
+ # current model is trained on 6 days of data because that is what will be
+ # available at runtime
+
+ # rolling time window interval size in days
+ roll_window_size = 6
+
+ # rolling means generator
+ dataset_size = disk_days_attrs.shape[0] - roll_window_size + 1
+ gen = (disk_days_attrs[i: i + roll_window_size, ...].mean(axis=0)
+ for i in range(dataset_size))
+ means = np.vstack(gen) # type: ignore
+
+ # rolling stds generator
+ gen = (disk_days_attrs[i: i + roll_window_size, ...].std(axis=0, ddof=1)
+ for i in range(dataset_size))
+ stds = np.vstack(gen) # type: ignore
+
+ # coefficient of variation
+ cvs = stds / means
+ cvs[np.isnan(cvs)] = 0
+ featurized = np.hstack((means,
+ stds,
+ cvs,
+ disk_days_sa['user_capacity'][: dataset_size].reshape(-1, 1)))
+
+ # scale features
+ scaler_path = os.path.join(self.model_dirpath, manufacturer + "_scaler.pkl")
+ with open(scaler_path, 'rb') as f:
+ scaler = pickle.load(f)
+ featurized = scaler.transform(featurized)
+ return featurized
+
+ @staticmethod
+ def __get_manufacturer(model_name: str) -> Optional[str]:
+ """Returns the manufacturer name for a given hard drive model name
+
+ Arguments:
+ model_name {str} -- hard drive model name
+
+ Returns:
+ str -- manufacturer name
+ """
+ for prefix, manufacturer in RHDiskFailurePredictor.MANUFACTURER_MODELNAME_PREFIXES.items():
+ if model_name.startswith(prefix):
+ return manufacturer.lower()
+ # print error message
+ RHDiskFailurePredictor.LOGGER.debug(
+ f"Could not infer manufacturer from model name {model_name}")
+ return None
+
+ def predict(self, disk_days: Sequence[DevSmartT]) -> str:
+ # get manufacturer preferably as a smartctl attribute
+ # if not available then infer using model name
+ manufacturer = disk_days[0].get("vendor")
+ if manufacturer is None:
+ RHDiskFailurePredictor.LOGGER.debug(
+ '"vendor" field not found in smartctl output. Will try to infer manufacturer from model name.'
+ )
+ manufacturer = RHDiskFailurePredictor.__get_manufacturer(
+ disk_days[0].get("model_name", ""))
+
+ # print error message, return Unknown, and continue execution
+ if manufacturer is None:
+ RHDiskFailurePredictor.LOGGER.debug(
+ "Manufacturer could not be determiend. This may be because \
+ DiskPredictor has never encountered this manufacturer before, \
+ or the model name is not according to the manufacturer's \
+ naming conventions known to DiskPredictor"
+ )
+ return RHDiskFailurePredictor.PREDICTION_CLASSES[-1]
+
+ # preprocess for feeding to model
+ preprocessed_data = self.__preprocess(disk_days, manufacturer)
+ if preprocessed_data is None:
+ return RHDiskFailurePredictor.PREDICTION_CLASSES[-1]
+
+ # get model for current manufacturer
+ model_path = os.path.join(
+ self.model_dirpath, manufacturer + "_predictor.pkl"
+ )
+ with open(model_path, 'rb') as f:
+ model = pickle.load(f)
+
+ # use prediction for most recent day
+ # TODO: ensure that most recent day is last element and most previous day
+ # is first element in input disk_days
+ pred_class_id = model.predict(preprocessed_data)[-1]
+ return RHDiskFailurePredictor.PREDICTION_CLASSES[pred_class_id]
+
+
+class PSDiskFailurePredictor(Predictor):
+ """Disk failure prediction developed at ProphetStor
+
+ This class implements a disk failure prediction module.
+ """
+
+ CONFIG_FILE = "config.json"
+ EXCLUDED_ATTRS = ["smart_9_raw", "smart_241_raw", "smart_242_raw"]
+
+ def __init__(self) -> None:
+ """
+ This function may throw exception due to wrong file operation.
+ """
+
+ self.model_dirpath = ""
+ self.model_context: Dict[str, List[str]] = {}
+
+ def initialize(self, model_dirpath: str) -> None:
+ """
+ Initialize all models.
+
+ Args: None
+
+ Returns:
+ Error message. If all goes well, return an empty string.
+
+ Raises:
+ """
+
+ config_path = os.path.join(model_dirpath, self.CONFIG_FILE)
+ if not os.path.isfile(config_path):
+ raise Exception(f"Missing config file: {config_path}")
+ with open(config_path) as f_conf:
+ self.model_context = json.load(f_conf)
+
+ for model_name in self.model_context:
+ model_path = os.path.join(model_dirpath, model_name)
+
+ if not os.path.isfile(model_path):
+ raise Exception(f"Missing model file: {model_path}")
+
+ self.model_dirpath = model_dirpath
+
+ def __preprocess(self, disk_days: Sequence[DevSmartT]) -> Sequence[DevSmartT]:
+ """
+ Preprocess disk attributes.
+
+ Args:
+ disk_days: Refer to function predict(...).
+
+ Returns:
+ new_disk_days: Processed disk days.
+ """
+
+ req_attrs = []
+ new_disk_days = []
+
+ attr_list = set.intersection(*[set(disk_day.keys()) for disk_day in disk_days])
+ for attr in attr_list:
+ if (
+ attr.startswith("smart_") and attr.endswith("_raw")
+ ) and attr not in self.EXCLUDED_ATTRS:
+ req_attrs.append(attr)
+
+ for disk_day in disk_days:
+ new_disk_day = {}
+ for attr in req_attrs:
+ if float(disk_day[attr]) >= 0.0:
+ new_disk_day[attr] = disk_day[attr]
+
+ new_disk_days.append(new_disk_day)
+
+ return new_disk_days
+
+ @staticmethod
+ def __get_diff_attrs(disk_days: Sequence[DevSmartT]) -> Tuple[AttrNamesT, AttrDiffsT]:
+ """
+ Get 5 days differential attributes.
+
+ Args:
+ disk_days: Refer to function predict(...).
+
+ Returns:
+ attr_list: All S.M.A.R.T. attributes used in given disk. Here we
+ use intersection set of all disk days.
+
+ diff_disk_days: A list struct comprises 5 dictionaries, each
+ dictionary contains differential attributes.
+
+ Raises:
+ Exceptions of wrong list/dict operations.
+ """
+
+ all_attrs = [set(disk_day.keys()) for disk_day in disk_days]
+ attr_list = list(set.intersection(*all_attrs))
+ prev_days = disk_days[:-1]
+ curr_days = disk_days[1:]
+ diff_disk_days = []
+ # TODO: ensure that this ordering is correct
+ for prev, cur in zip(prev_days, curr_days):
+ diff_disk_days.append(
+ {attr: (int(cur[attr]) - int(prev[attr])) for attr in attr_list}
+ )
+
+ return attr_list, diff_disk_days
+
+ def __get_best_models(self, attr_list: AttrNamesT) -> Optional[Dict[str, List[str]]]:
+ """
+ Find the best model from model list according to given attribute list.
+
+ Args:
+ attr_list: All S.M.A.R.T. attributes used in given disk.
+
+ Returns:
+ modelpath: The best model for the given attribute list.
+ model_attrlist: 'Ordered' attribute list of the returned model.
+ Must be aware that SMART attributes is in order.
+
+ Raises:
+ """
+
+ models = self.model_context.keys()
+
+ scores = []
+ for model_name in models:
+ scores.append(
+ sum(attr in attr_list for attr in self.model_context[model_name])
+ )
+ max_score = max(scores)
+
+ # Skip if too few matched attributes.
+ if max_score < 3:
+ print("Too few matched attributes")
+ return None
+
+ best_models: Dict[str, List[str]] = {}
+ best_model_indices = [
+ idx for idx, score in enumerate(scores) if score > max_score - 2
+ ]
+ for model_idx in best_model_indices:
+ model_name = list(models)[model_idx]
+ model_path = os.path.join(self.model_dirpath, model_name)
+ model_attrlist = self.model_context[model_name]
+ best_models[model_path] = model_attrlist
+
+ return best_models
+ # return os.path.join(self.model_dirpath, model_name), model_attrlist
+
+ @staticmethod
+ def __get_ordered_attrs(disk_days: Sequence[DevSmartT], model_attrlist: List[str]) -> List[List[float]]:
+ """
+ Return ordered attributes of given disk days.
+
+ Args:
+ disk_days: Unordered disk days.
+ model_attrlist: Model's ordered attribute list.
+
+ Returns:
+ ordered_attrs: Ordered disk days.
+
+ Raises: None
+ """
+
+ ordered_attrs = []
+
+ for one_day in disk_days:
+ one_day_attrs = []
+
+ for attr in model_attrlist:
+ if attr in one_day:
+ one_day_attrs.append(one_day[attr])
+ else:
+ one_day_attrs.append(0)
+
+ ordered_attrs.append(one_day_attrs)
+
+ return ordered_attrs
+
+ def predict(self, disk_days: Sequence[DevSmartT]) -> str:
+ """
+ Predict using given 6-days disk S.M.A.R.T. attributes.
+
+ Args:
+ disk_days: A list struct comprises 6 dictionaries. These
+ dictionaries store 'consecutive' days of disk SMART
+ attributes.
+ Returns:
+ A string indicates prediction result. One of following four strings
+ will be returned according to disk failure status:
+ (1) Good : Disk is health
+ (2) Warning : Disk has some symptoms but may not fail immediately
+ (3) Bad : Disk is in danger and data backup is highly recommended
+ (4) Unknown : Not enough data for prediction.
+
+ Raises:
+ Pickle exceptions
+ """
+
+ all_pred = []
+
+ proc_disk_days = self.__preprocess(disk_days)
+ attr_list, diff_data = PSDiskFailurePredictor.__get_diff_attrs(proc_disk_days)
+ modellist = self.__get_best_models(attr_list)
+ if modellist is None:
+ return "Unknown"
+
+ for modelpath in modellist:
+ model_attrlist = modellist[modelpath]
+ ordered_data = PSDiskFailurePredictor.__get_ordered_attrs(
+ diff_data, model_attrlist
+ )
+
+ try:
+ with open(modelpath, "rb") as f_model:
+ clf = pickle.load(f_model)
+
+ except UnicodeDecodeError:
+ # Compatibility for python3
+ with open(modelpath, "rb") as f_model:
+ clf = pickle.load(f_model, encoding="latin1")
+
+ pred = clf.predict(ordered_data)
+
+ all_pred.append(1 if any(pred) else 0)
+
+ score = 2 ** sum(all_pred) - len(modellist)
+ if score > 10:
+ return "Bad"
+ if score > 4:
+ return "Warning"
+ return "Good"
diff --git a/src/pybind/mgr/diskprediction_local/requirements.txt b/src/pybind/mgr/diskprediction_local/requirements.txt
new file mode 100644
index 000000000..d9c3157fd
--- /dev/null
+++ b/src/pybind/mgr/diskprediction_local/requirements.txt
@@ -0,0 +1,3 @@
+numpy==1.15.1
+scipy==1.1.0
+scikit-learn==0.19.2