Initial Stages
This commit is contained in:
199118
clusterwide-file-manifest/8-1-3/clusterwide-manifest.nmd5
Normal file
199118
clusterwide-file-manifest/8-1-3/clusterwide-manifest.nmd5
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
md5sum: /var/cache/salt/minion/proc/20260216150131518310: No such file or directory
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
clusterwide-file-manifest/8-1-3/source/manifests-813.tar.gz
Normal file
BIN
clusterwide-file-manifest/8-1-3/source/manifests-813.tar.gz
Normal file
Binary file not shown.
253026
clusterwide-file-manifest/8-2/clusterwide-manifest.nmd5
Normal file
253026
clusterwide-file-manifest/8-2/clusterwide-manifest.nmd5
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
md5sum: /var/cache/salt/master/jobs/01/312f959b21aac3a07b1911b168bdd043d22a702d2f2939013fae3c868b1693/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/01/312f959b21aac3a07b1911b168bdd043d22a702d2f2939013fae3c868b1693/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/01/312f959b21aac3a07b1911b168bdd043d22a702d2f2939013fae3c868b1693/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/01/312f959b21aac3a07b1911b168bdd043d22a702d2f2939013fae3c868b1693/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/05/17d86915b811bf02578c15fc76388cdb61d2674645480d0ae9f3378c0c71fa/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/05/17d86915b811bf02578c15fc76388cdb61d2674645480d0ae9f3378c0c71fa/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/05/17d86915b811bf02578c15fc76388cdb61d2674645480d0ae9f3378c0c71fa/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/05/17d86915b811bf02578c15fc76388cdb61d2674645480d0ae9f3378c0c71fa/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/06/36f2d9524cd433a2321fb1c3427f6e8779ff7655baa42e4766c22aef79b04f/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/06/36f2d9524cd433a2321fb1c3427f6e8779ff7655baa42e4766c22aef79b04f/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/06/36f2d9524cd433a2321fb1c3427f6e8779ff7655baa42e4766c22aef79b04f/4b78f943-203d-4ae5-b4fe-dae35bd4d157/out.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/06/36f2d9524cd433a2321fb1c3427f6e8779ff7655baa42e4766c22aef79b04f/4b78f943-203d-4ae5-b4fe-dae35bd4d157/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/06/36f2d9524cd433a2321fb1c3427f6e8779ff7655baa42e4766c22aef79b04f/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/2b/06e64cb00c211a61e72ae765a8f87618692d467d271254db2ff1d6476a266a/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/2b/06e64cb00c211a61e72ae765a8f87618692d467d271254db2ff1d6476a266a/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/2b/06e64cb00c211a61e72ae765a8f87618692d467d271254db2ff1d6476a266a/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/2b/06e64cb00c211a61e72ae765a8f87618692d467d271254db2ff1d6476a266a/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/3f/123e0ca05ed360884fbc67a74834060c46da6a3216df587ee939e8722e96a0/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/3f/123e0ca05ed360884fbc67a74834060c46da6a3216df587ee939e8722e96a0/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/3f/123e0ca05ed360884fbc67a74834060c46da6a3216df587ee939e8722e96a0/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/3f/123e0ca05ed360884fbc67a74834060c46da6a3216df587ee939e8722e96a0/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/49/c0fdef6821532e4b2fa74d59945242ba23f1f583dd79d80012289150188098/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/49/c0fdef6821532e4b2fa74d59945242ba23f1f583dd79d80012289150188098/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/49/c0fdef6821532e4b2fa74d59945242ba23f1f583dd79d80012289150188098/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/49/c0fdef6821532e4b2fa74d59945242ba23f1f583dd79d80012289150188098/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/50/5b1c4e5a6093c895296969a8e8b6305b31326d05e20208d30b5b38d9ed9688/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/50/5b1c4e5a6093c895296969a8e8b6305b31326d05e20208d30b5b38d9ed9688/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/50/5b1c4e5a6093c895296969a8e8b6305b31326d05e20208d30b5b38d9ed9688/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/50/5b1c4e5a6093c895296969a8e8b6305b31326d05e20208d30b5b38d9ed9688/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/51/c0a9a331599fdb4bddd5b1597ead17ba1f96ea1799ef4133480a5ae2278929/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/51/c0a9a331599fdb4bddd5b1597ead17ba1f96ea1799ef4133480a5ae2278929/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/51/c0a9a331599fdb4bddd5b1597ead17ba1f96ea1799ef4133480a5ae2278929/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/51/c0a9a331599fdb4bddd5b1597ead17ba1f96ea1799ef4133480a5ae2278929/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/58/7a995a41151b396d1c3b570d598a56804aaea767691e11a8ab59645e9c52cd/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/58/7a995a41151b396d1c3b570d598a56804aaea767691e11a8ab59645e9c52cd/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/58/7a995a41151b396d1c3b570d598a56804aaea767691e11a8ab59645e9c52cd/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/58/7a995a41151b396d1c3b570d598a56804aaea767691e11a8ab59645e9c52cd/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/5e/cefd947d3e51090dcce6cf1fc4bbec19d2680b96982902d5146b957803b7dd/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/5e/cefd947d3e51090dcce6cf1fc4bbec19d2680b96982902d5146b957803b7dd/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/5e/cefd947d3e51090dcce6cf1fc4bbec19d2680b96982902d5146b957803b7dd/a30b5c95-29c4-4b8e-998c-2013a15d9333/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/5e/cefd947d3e51090dcce6cf1fc4bbec19d2680b96982902d5146b957803b7dd/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/1608dfce11b6c1cffa8c79cfbeb117b75d4abe85c73f231a43d0621e7f313a/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/1608dfce11b6c1cffa8c79cfbeb117b75d4abe85c73f231a43d0621e7f313a/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/1608dfce11b6c1cffa8c79cfbeb117b75d4abe85c73f231a43d0621e7f313a/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/1608dfce11b6c1cffa8c79cfbeb117b75d4abe85c73f231a43d0621e7f313a/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/2f74f122fd04ca11181d3493c2d106cb01aaa6c3bc031d555980a18fc9dd87/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/2f74f122fd04ca11181d3493c2d106cb01aaa6c3bc031d555980a18fc9dd87/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/2f74f122fd04ca11181d3493c2d106cb01aaa6c3bc031d555980a18fc9dd87/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/72/2f74f122fd04ca11181d3493c2d106cb01aaa6c3bc031d555980a18fc9dd87/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/84/b8a292785548744e8c08fa2054db5afb24ab2598e3c0b6da6282cd24596dc3/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/84/b8a292785548744e8c08fa2054db5afb24ab2598e3c0b6da6282cd24596dc3/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/84/b8a292785548744e8c08fa2054db5afb24ab2598e3c0b6da6282cd24596dc3/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/84/b8a292785548744e8c08fa2054db5afb24ab2598e3c0b6da6282cd24596dc3/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/95/93687fae345fb23193b151e69b9c91a6b453fa27f4534b6a46357a2ff9fda0/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/95/93687fae345fb23193b151e69b9c91a6b453fa27f4534b6a46357a2ff9fda0/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/95/93687fae345fb23193b151e69b9c91a6b453fa27f4534b6a46357a2ff9fda0/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/95/93687fae345fb23193b151e69b9c91a6b453fa27f4534b6a46357a2ff9fda0/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/aa/ec3b0943ecf723a0a4d126e4b7d161100308a8c5c19efab09985323011206c/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/aa/ec3b0943ecf723a0a4d126e4b7d161100308a8c5c19efab09985323011206c/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/aa/ec3b0943ecf723a0a4d126e4b7d161100308a8c5c19efab09985323011206c/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/aa/ec3b0943ecf723a0a4d126e4b7d161100308a8c5c19efab09985323011206c/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/b4/349af986e29ef410c551a4de924ffbf1afd4e4941eb355d2a9f2b254c31bab/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/b4/349af986e29ef410c551a4de924ffbf1afd4e4941eb355d2a9f2b254c31bab/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/b4/349af986e29ef410c551a4de924ffbf1afd4e4941eb355d2a9f2b254c31bab/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/b4/349af986e29ef410c551a4de924ffbf1afd4e4941eb355d2a9f2b254c31bab/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bb/e4b07a318619ee776d7a041dd1437fc687435ac1963fef0f9c06dd67dd92a8/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bb/e4b07a318619ee776d7a041dd1437fc687435ac1963fef0f9c06dd67dd92a8/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bb/e4b07a318619ee776d7a041dd1437fc687435ac1963fef0f9c06dd67dd92a8/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bb/e4b07a318619ee776d7a041dd1437fc687435ac1963fef0f9c06dd67dd92a8/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bd/d07ad5212a593b54f58ffa22b9ea2d7df84f4793e4de0f84b4405b802d6930/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bd/d07ad5212a593b54f58ffa22b9ea2d7df84f4793e4de0f84b4405b802d6930/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bd/d07ad5212a593b54f58ffa22b9ea2d7df84f4793e4de0f84b4405b802d6930/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/bd/d07ad5212a593b54f58ffa22b9ea2d7df84f4793e4de0f84b4405b802d6930/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c3/c379258b5e0a20ceae27c99701df65c5a2d9aa28ebad703da858079e0c4aa2/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c3/c379258b5e0a20ceae27c99701df65c5a2d9aa28ebad703da858079e0c4aa2/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c3/c379258b5e0a20ceae27c99701df65c5a2d9aa28ebad703da858079e0c4aa2/9398ab4f-fca3-4ad5-b0cc-d1b57326dc94/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c3/c379258b5e0a20ceae27c99701df65c5a2d9aa28ebad703da858079e0c4aa2/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c6/318e9ff9714ba3561bd8f2c85ccf9b6e42c38449ff84150e5219a40599185f/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c6/318e9ff9714ba3561bd8f2c85ccf9b6e42c38449ff84150e5219a40599185f/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c6/318e9ff9714ba3561bd8f2c85ccf9b6e42c38449ff84150e5219a40599185f/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/c6/318e9ff9714ba3561bd8f2c85ccf9b6e42c38449ff84150e5219a40599185f/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/ca/edd63c29a5fea6bd83ac08b7d55d306ba96644750e36907b690d546de3d510/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/ca/edd63c29a5fea6bd83ac08b7d55d306ba96644750e36907b690d546de3d510/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/ca/edd63c29a5fea6bd83ac08b7d55d306ba96644750e36907b690d546de3d510/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/ca/edd63c29a5fea6bd83ac08b7d55d306ba96644750e36907b690d546de3d510/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/d5/fd88747e5b396a6aa45bf614bba3d1f5ed5e68b321d6c72c6a0e543faf37f7/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/d5/fd88747e5b396a6aa45bf614bba3d1f5ed5e68b321d6c72c6a0e543faf37f7/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/d5/fd88747e5b396a6aa45bf614bba3d1f5ed5e68b321d6c72c6a0e543faf37f7/4b78f943-203d-4ae5-b4fe-dae35bd4d157/out.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/d5/fd88747e5b396a6aa45bf614bba3d1f5ed5e68b321d6c72c6a0e543faf37f7/4b78f943-203d-4ae5-b4fe-dae35bd4d157/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/d5/fd88747e5b396a6aa45bf614bba3d1f5ed5e68b321d6c72c6a0e543faf37f7/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/e8/2d9fc5b4f43343b89ee05583e1b30489dbebe28fee01b6a677126e3f5d6c68/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/e8/2d9fc5b4f43343b89ee05583e1b30489dbebe28fee01b6a677126e3f5d6c68/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/e8/2d9fc5b4f43343b89ee05583e1b30489dbebe28fee01b6a677126e3f5d6c68/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/e8/2d9fc5b4f43343b89ee05583e1b30489dbebe28fee01b6a677126e3f5d6c68/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/f4/6b7cb33be729defed16e3b50595c8da005018d7d61f30c33232e732627e5f5/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/f4/6b7cb33be729defed16e3b50595c8da005018d7d61f30c33232e732627e5f5/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/f4/6b7cb33be729defed16e3b50595c8da005018d7d61f30c33232e732627e5f5/4b78f943-203d-4ae5-b4fe-dae35bd4d157_master/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/f4/6b7cb33be729defed16e3b50595c8da005018d7d61f30c33232e732627e5f5/jid: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/fc/2e0a5e7b4023da0694f5b1f85a29e3be1ff28be753506d7c37e89f3cbcf76e/.load.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/fc/2e0a5e7b4023da0694f5b1f85a29e3be1ff28be753506d7c37e89f3cbcf76e/.minions.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/fc/2e0a5e7b4023da0694f5b1f85a29e3be1ff28be753506d7c37e89f3cbcf76e/9398ab4f-fca3-4ad5-b0cc-d1b57326dc94/out.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/fc/2e0a5e7b4023da0694f5b1f85a29e3be1ff28be753506d7c37e89f3cbcf76e/9398ab4f-fca3-4ad5-b0cc-d1b57326dc94/return.p: No such file or directory
|
||||
md5sum: /var/cache/salt/master/jobs/fc/2e0a5e7b4023da0694f5b1f85a29e3be1ff28be753506d7c37e89f3cbcf76e/jid: No such file or directory
|
||||
@@ -0,0 +1 @@
|
||||
md5sum: /var/cache/salt/minion/proc/20260216124853879978: No such file or directory
|
||||
29895
clusterwide-file-manifest/8-2/source/opt-manifest-node01.txt
Normal file
29895
clusterwide-file-manifest/8-2/source/opt-manifest-node01.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
clusterwide-file-manifest/8-2/source/test.tar.gz
Normal file
BIN
clusterwide-file-manifest/8-2/source/test.tar.gz
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
29423
clusterwide-file-manifest/test/opt-manifest-8-1-3.testcluster.txt
Normal file
29423
clusterwide-file-manifest/test/opt-manifest-8-1-3.testcluster.txt
Normal file
File diff suppressed because it is too large
Load Diff
28
readme.md
Normal file
28
readme.md
Normal file
@@ -0,0 +1,28 @@
|
||||
Under clusterwide-file-manifest we should have directory tree of the form
|
||||
|
||||
dir - K-Y-Z-M
|
||||
K-Y-Z-M/clusterwide-manifest.nmd5
|
||||
|
||||
These are the clusterwide manifests - i.e manifests that are produced by comparing the md5s of different nodes from the same cluster,
|
||||
and producing 2 lists for each of those clusters:
|
||||
|
||||
List 1 (matches):
|
||||
md5sum:/file/path
|
||||
|
||||
List 2 (diffs):
|
||||
md5sum:/file/path
|
||||
|
||||
Where List 1 is a list of all files that have the same path, and have the same path and md5sum across the cluster
|
||||
While list 2 is a list of the inverse of the above.
|
||||
|
||||
# Stages
|
||||
|
||||
## Stage 1 - Md5:filepath
|
||||
- Param 1 - base path (i.e `stage1.sh /` - would produce md5sum for everything under root)
|
||||
- Produces a file containing the md5:file on a given system
|
||||
- Excludes directories known to contain node-specific directories
|
||||
|
||||
## Stage 2 - Base manifest producer -
|
||||
Takes in files produced from Stage 1 across a cluster and produces an output base-manifest
|
||||
|
||||
## Stage 3 - Compares a stage 1 output against a known stage 2 manifest
|
||||
55
stages/stage1-gather-node-manifest.sh
Normal file
55
stages/stage1-gather-node-manifest.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
# manifest_gen.sh — minimal manifest generator using find + md5sum
|
||||
# Default output: /tmp/manifest-<hostname>.txt
|
||||
# Format: "<md5> <absolute_path>"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HOST="$(hostname -s 2>/dev/null || hostname 2>/dev/null || echo unknown)"
|
||||
OUT="./manifest-${HOST}.txt"
|
||||
ROOT="${1:-/}"
|
||||
|
||||
# Default excludes (edit here)
|
||||
EXCLUDES=(/proc /sys /dev /run /tmp /var/run /var/lock /lost+found /mnt /media /cloudian* /var/lib/cassandra)
|
||||
|
||||
ERR="${OUT}.err"
|
||||
: > "$OUT"
|
||||
: > "$ERR"
|
||||
|
||||
ROOT="$(cd "$ROOT" && pwd -P)"
|
||||
|
||||
{
|
||||
echo "# manifest_version=md5sum-v1"
|
||||
echo "# created_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
echo "# host=$HOST"
|
||||
echo "# root=$ROOT"
|
||||
echo -n "# excludes="
|
||||
printf "%s " "${EXCLUDES[@]}"
|
||||
echo
|
||||
echo "# format=<md5> <absolute_path>"
|
||||
} >> "$OUT"
|
||||
|
||||
# Build prune expression
|
||||
PRUNE=()
|
||||
for ex in "${EXCLUDES[@]}"; do
|
||||
# normalize excludes if they exist; if they don't, still keep as-is
|
||||
if [ -e "$ex" ]; then
|
||||
ex="$(cd "$ex" 2>/dev/null && pwd -P || echo "$ex")"
|
||||
fi
|
||||
PRUNE+=( -path "$ex" -o -path "$ex/*" -o )
|
||||
done
|
||||
unset 'PRUNE[${#PRUNE[@]}-1]' # drop last -o
|
||||
|
||||
# Deterministic ordering if available (GNU sort -z)
|
||||
if sort -z </dev/null >/dev/null 2>&1; then
|
||||
find "$ROOT" \( "${PRUNE[@]}" \) -prune -o -type f -print0 2>>"$ERR" \
|
||||
| sort -z 2>>"$ERR" \
|
||||
| xargs -0 -r md5sum -- 2>>"$ERR" >> "$OUT"
|
||||
else
|
||||
find "$ROOT" \( "${PRUNE[@]}" \) -prune -o -type f -print0 2>>"$ERR" \
|
||||
| xargs -0 -r md5sum -- 2>>"$ERR" >> "$OUT"
|
||||
fi
|
||||
|
||||
echo "Wrote: $OUT" >&2
|
||||
echo "Errs: $ERR" >&2
|
||||
134
stages/stage2-analyze-clusterwide-manifests.py
Normal file
134
stages/stage2-analyze-clusterwide-manifests.py
Normal file
@@ -0,0 +1,134 @@
|
||||
import os
|
||||
import glob
|
||||
import json
|
||||
import argparse
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
def parse_node_manifest(filepath):
|
||||
"""
|
||||
Parses a single node manifest file.
|
||||
Returns:
|
||||
host (str): The hostname found in the header.
|
||||
file_data (dict): Dictionary { filepath: md5_hash }
|
||||
"""
|
||||
host = None
|
||||
file_data = {}
|
||||
|
||||
try:
|
||||
with open(filepath, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# Parse Headers
|
||||
if line.startswith('#'):
|
||||
if line.startswith('# host='):
|
||||
host = line.split('=')[1].strip()
|
||||
continue
|
||||
|
||||
# Parse Data (md5 absolute_path)
|
||||
# We split by whitespace, maxsplit=1 to preserve spaces in filenames if they exist
|
||||
parts = line.split(maxsplit=1)
|
||||
if len(parts) == 2:
|
||||
md5, path = parts
|
||||
file_data[path] = md5
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error reading file {filepath}: {e}", file=sys.stderr)
|
||||
return None, None
|
||||
|
||||
if not host:
|
||||
print(f"Warning: No '# host=' header found in {filepath}. Using filename as ID.", file=sys.stderr)
|
||||
host = os.path.basename(filepath)
|
||||
|
||||
return host, file_data
|
||||
|
||||
def generate_golden_manifest(input_dir, output_file):
|
||||
manifest_files = glob.glob(os.path.join(input_dir, '*'))
|
||||
|
||||
if not manifest_files:
|
||||
print(f"No files found in directory: {input_dir}")
|
||||
return
|
||||
|
||||
# 1. Aggregation Phase
|
||||
# Structure: global_registry[filepath] = { hostname: hash }
|
||||
global_registry = defaultdict(dict)
|
||||
all_hosts = set()
|
||||
|
||||
print(f"Scanning {len(manifest_files)} manifests...")
|
||||
|
||||
for fpath in manifest_files:
|
||||
# Skip if it's a directory
|
||||
if os.path.isdir(fpath):
|
||||
continue
|
||||
|
||||
host, data = parse_node_manifest(fpath)
|
||||
if host and data:
|
||||
all_hosts.add(host)
|
||||
for path, md5 in data.items():
|
||||
global_registry[path][host] = md5
|
||||
|
||||
# 2. Analysis Phase
|
||||
cluster_manifest = {
|
||||
"meta": {
|
||||
"total_hosts": len(all_hosts),
|
||||
"hosts": list(sorted(all_hosts)),
|
||||
"generated_at": str(os.path.basename(output_file))
|
||||
},
|
||||
"consistent_files": {}, # Files identical on ALL hosts
|
||||
"varying_files": {} # Files that differ or are missing on some hosts
|
||||
}
|
||||
|
||||
print("Analyzing file consistency...")
|
||||
|
||||
for path, host_map in global_registry.items():
|
||||
unique_hashes = set(host_map.values())
|
||||
present_on_hosts = set(host_map.keys())
|
||||
|
||||
# Condition 1: Consistent
|
||||
# Present on ALL hosts AND has exactly 1 unique hash
|
||||
if present_on_hosts == all_hosts and len(unique_hashes) == 1:
|
||||
# Store just the hash, as it is the "Ground Truth"
|
||||
cluster_manifest["consistent_files"][path] = list(unique_hashes)[0]
|
||||
|
||||
# Condition 2: Varying
|
||||
else:
|
||||
issue_type = []
|
||||
if len(unique_hashes) > 1:
|
||||
issue_type.append("hash_mismatch")
|
||||
if present_on_hosts != all_hosts:
|
||||
issue_type.append("presence_mismatch")
|
||||
|
||||
# For varying files, we need the specific details per host
|
||||
# so the comparison tool knows what to expect where.
|
||||
|
||||
# Fill in "MISSING" for hosts that don't have the file
|
||||
full_map = host_map.copy()
|
||||
for h in all_hosts:
|
||||
if h not in full_map:
|
||||
full_map[h] = "MISSING"
|
||||
|
||||
cluster_manifest["varying_files"][path] = {
|
||||
"issues": issue_type,
|
||||
"states": full_map
|
||||
}
|
||||
|
||||
# 3. Output Phase
|
||||
try:
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(cluster_manifest, f, indent=2, sort_keys=True)
|
||||
print(f"Success! Cluster manifest written to: {output_file}")
|
||||
print(f"Stats: {len(cluster_manifest['consistent_files'])} consistent files, {len(cluster_manifest['varying_files'])} varying files.")
|
||||
except Exception as e:
|
||||
print(f"Error writing output file: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate a cluster-wide ground truth manifest.")
|
||||
parser.add_argument("input_dir", help="Directory containing node manifest files")
|
||||
parser.add_argument("output_file", help="Path to write the resulting JSON manifest")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_golden_manifest(args.input_dir, args.output_file)
|
||||
168
stages/stage3-compare-sub-manifest-c.py
Normal file
168
stages/stage3-compare-sub-manifest-c.py
Normal file
@@ -0,0 +1,168 @@
|
||||
import json
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
def parse_manifest_file(filepath):
|
||||
"""
|
||||
Parses the target sub-manifest file to extract host and file hashes.
|
||||
"""
|
||||
host = None
|
||||
file_data = {}
|
||||
|
||||
try:
|
||||
with open(filepath, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line: continue
|
||||
|
||||
# Extract Header Hostname
|
||||
if line.startswith('#'):
|
||||
if line.startswith('# host='):
|
||||
host = line.split('=')[1].strip()
|
||||
continue
|
||||
|
||||
# Extract Hash and Path
|
||||
parts = line.split(maxsplit=1)
|
||||
if len(parts) == 2:
|
||||
md5, path = parts
|
||||
file_data[path] = md5
|
||||
|
||||
except Exception as e:
|
||||
print(f"Critical Error: Could not read manifest file: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if not host:
|
||||
print("Warning: No '# host=' header found. Validation of 'varying' files will be impossible.")
|
||||
|
||||
return host, file_data
|
||||
|
||||
def compare_against_research(manifest_path, research_path):
|
||||
# 1. Load the Ground Truth (Research)
|
||||
try:
|
||||
with open(research_path, 'r') as f:
|
||||
research = json.load(f)
|
||||
except Exception as e:
|
||||
print(f"Critical Error: Could not load research JSON: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# 2. Parse the Sub-Manifest (Target)
|
||||
target_host, target_files = parse_manifest_file(manifest_path)
|
||||
|
||||
print(f"--- VALIDATION REPORT ---")
|
||||
print(f"Target Host: {target_host if target_host else 'UNKNOWN'}")
|
||||
print(f"Files Scanned: {len(target_files)}")
|
||||
print(f"Research Baseline: {research['meta']['total_hosts']} hosts known")
|
||||
print("-" * 30)
|
||||
|
||||
# Buckets for results
|
||||
results = {
|
||||
"ok_consistent": [], # Matches cluster-wide invariant
|
||||
"ok_varying": [], # Matches expected value for this specific host
|
||||
"fail_consistent": [], # Violated a cluster-wide invariant
|
||||
"fail_varying": [], # Violated the specific expectation for this host
|
||||
"unknown_file": [], # File not present in original research
|
||||
"unverifiable_host": [] # File is varying, but we don't know this host
|
||||
}
|
||||
|
||||
# 3. The Comparison Logic
|
||||
for fpath, fhash in target_files.items():
|
||||
|
||||
# CHECK A: Is it a Known Consistent File?
|
||||
if fpath in research['consistent_files']:
|
||||
expected_hash = research['consistent_files'][fpath]
|
||||
if fhash == expected_hash:
|
||||
results['ok_consistent'].append(fpath)
|
||||
else:
|
||||
results['fail_consistent'].append({
|
||||
"path": fpath,
|
||||
"found": fhash,
|
||||
"expected": expected_hash
|
||||
})
|
||||
|
||||
# CHECK B: Is it a Known Varying File?
|
||||
elif fpath in research['varying_files']:
|
||||
# We need the hostname to validate varying files
|
||||
if not target_host:
|
||||
results['unverifiable_host'].append(fpath)
|
||||
continue
|
||||
|
||||
node_states = research['varying_files'][fpath]['states']
|
||||
|
||||
# Does the research know about this host?
|
||||
if target_host in node_states:
|
||||
expected_hash = node_states[target_host]
|
||||
|
||||
if expected_hash == "MISSING":
|
||||
# We found a file that research says shouldn't exist on this node
|
||||
results['fail_varying'].append({
|
||||
"path": fpath,
|
||||
"found": fhash,
|
||||
"expected": "File should not exist on this node"
|
||||
})
|
||||
elif fhash == expected_hash:
|
||||
results['ok_varying'].append(fpath)
|
||||
else:
|
||||
results['fail_varying'].append({
|
||||
"path": fpath,
|
||||
"found": fhash,
|
||||
"expected": expected_hash
|
||||
})
|
||||
else:
|
||||
# This is a new host not in the original research
|
||||
# We can't validate varying files for unknown hosts
|
||||
results['unverifiable_host'].append(fpath)
|
||||
|
||||
# CHECK C: Unknown File
|
||||
else:
|
||||
results['unknown_file'].append(fpath)
|
||||
|
||||
# 4. Print Summary
|
||||
# OK Sections
|
||||
if results['ok_consistent']:
|
||||
print(f"\n[PASS] Consistent Files Verified: {len(results['ok_consistent'])}")
|
||||
if results['ok_varying']:
|
||||
print(f"[PASS] Varying Files Verified: {len(results['ok_varying'])}")
|
||||
|
||||
# FAIL Sections
|
||||
if results['fail_consistent']:
|
||||
print(f"\n[FAIL] GLOBAL CONSISTENCY VIOLATIONS ({len(results['fail_consistent'])})")
|
||||
print("These files MUST be identical across the cluster but differed:")
|
||||
for item in results['fail_consistent']:
|
||||
print(f" X {item['path']}")
|
||||
print(f" Expected: {item['expected']}")
|
||||
print(f" Found: {item['found']}")
|
||||
|
||||
if results['fail_varying']:
|
||||
print(f"\n[FAIL] NODE SPECIFIC VIOLATIONS ({len(results['fail_varying'])})")
|
||||
print(f"These files did not match the expected state for {target_host}:")
|
||||
for item in results['fail_varying']:
|
||||
print(f" X {item['path']}")
|
||||
print(f" Expected: {item['expected']}")
|
||||
print(f" Found: {item['found']}")
|
||||
|
||||
# WARNING Sections
|
||||
if results['unknown_file']:
|
||||
print(f"\n[WARN] UNKNOWN FILES ({len(results['unknown_file'])})")
|
||||
print("These files were not seen in the original research scan:")
|
||||
for f in results['unknown_file'][:5]: print(f" ? {f}")
|
||||
if len(results['unknown_file']) > 5: print(f" ... and {len(results['unknown_file'])-5} more")
|
||||
|
||||
if results['unverifiable_host']:
|
||||
print(f"\n[WARN] UNVERIFIABLE FILES ({len(results['unverifiable_host'])})")
|
||||
print("These files vary per-node, but this host is new/unknown to the research:")
|
||||
for f in results['unverifiable_host'][:5]: print(f" ? {f}")
|
||||
|
||||
# Exit Code
|
||||
if results['fail_consistent'] or results['fail_varying']:
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Validate a sub-manifest against cluster research.")
|
||||
parser.add_argument("sub_manifest", help="The partial manifest file (subdir scan)")
|
||||
parser.add_argument("research_json", help="The cluster_ground_truth.json file")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
compare_against_research(args.sub_manifest, args.research_json)
|
||||
Reference in New Issue
Block a user