Compare commits

4 Commits

Author SHA1 Message Date
root
298e1ce3cd 8.2.2.3 2026-03-24 11:25:27 +00:00
N S
e19a8d715c Update readme.md 2026-03-24 10:13:57 +00:00
root
c90ba02813 8-2-2 testcluster 2026-03-24 10:05:35 +00:00
root
b66c400a2c spring-cleaning 2026-03-24 09:35:12 +00:00
28 changed files with 1510600 additions and 453 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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

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

View File

@@ -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

View File

@@ -0,0 +1 @@
md5sum: /var/cache/salt/minion/proc/20260216124853879978: No such file or directory

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +1,3 @@
Under clusterwide-file-manifest we should have directory tree of the form
This is the hs-manifests branch.
This should be for housing the relation between files on the system + their md5s, compared across a testcluster of 3 nodes on the same version.
`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 0 - ssh backbone for propogating stage1 across the cluster
```bash
yum install git -y
git clone https://git.adspem.com/opthq/nmd-md5sum-manifest.git
cd nmd-md5sum-manifest/stages
chmod +x *
./stage0-remote-run.sh
hsctl cmd run 'ls -la /root/manifest*'
./stage1-1-get-remote-files.sh
```
## 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

View File

@@ -1,25 +0,0 @@
#!/bin/bash
ssh_keyfile='/export/home/cloudian/cloudian-installation-key'
script='stage1-gather-node-manifest.sh'
# Ensure environment variables are set
if [[ -z "$ssh_keyfile" || -z "$script" ]]; then
echo "Error: Please set 'ssh_keyfile' and 'script' environment variables."
exit 1
fi
# Extract hostnames/IPs from /etc/hosts, skipping comments and localhost
HOSTS=$(grep -v '^#' /etc/hosts | grep -v 'localhost' | awk '{print $2}')
for HOST in $HOSTS; do
echo "--- Executing on: $HOST ---"
# Run the local script on the remote host using bash -s
# -i: Uses the specified ssh_keyfile
# -o StrictHostKeyChecking=no: Prevents the script from hanging on new host prompts
ssh -i "$ssh_keyfile" -o StrictHostKeyChecking=no "$HOST" "bash -s" < "$script"
# The loop naturally waits for the SSH command to finish before the next iteration
echo "--- Finished: $HOST ---"
done

View File

@@ -1,34 +0,0 @@
#!/bin/bash
ssh_keyfile='/export/home/cloudian/cloudian-installation-key'
# Set the path to the remote file you want to download
remote_file='/root/manifest-*txt*'
# Ensure variables are set
if [[ -z "$ssh_keyfile" || -z "$remote_file" ]]; then
echo "Error: Please set 'ssh_keyfile' and 'remote_file' variables."
exit 1
fi
# Extract hostnames/IPs from /etc/hosts, skipping comments and localhost
HOSTS=$(grep -v '^#' /etc/hosts | grep -v 'localhost' | awk '{print $2}')
for HOST in $HOSTS; do
echo "--- Fetching from: $HOST ---"
# Create a unique local directory for this host's file
#target_dir="remotes/$HOST"
target_dir="remotes/"
mkdir -p "$target_dir"
# Use SCP to pull the file from the remote host to the local directory
# -i: Specifies the identity (private key) file
# -o StrictHostKeyChecking=no: Skips manual fingerprint verification prompts
scp -i "$ssh_keyfile" -o StrictHostKeyChecking=no "$HOST":"$remote_file" "$target_dir/"
if [ $? -eq 0 ]; then
echo "--- Success: File saved to $target_dir/ ---"
else
echo "--- Failed: Could not fetch from $HOST ---"
fi
done

View File

@@ -1,55 +0,0 @@
#!/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

View File

@@ -1,134 +0,0 @@
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)

View File

@@ -1,168 +0,0 @@
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)