11from __future__ import annotations
2+ import sys
23import asyncio
3- from typing import Literal
4+ from pathlib import Path
45
56import yaml
67from pydantic import BaseModel
78
89from deploy .config import Config , AreaConfig
910
10- COLLECTOR = b"""\
11- #!/usr/bin/env python3
12- import os
13- import json
14- import re
15-
16-
17- def gather_versions() -> None:
18- print("versions:")
19- base = "/prog/pflotran/versions"
20- for name in os.listdir(base):
21- if name[0] == ".":
22- continue
23- path = os.path.join(base, name)
24- if os.path.islink(path):
25- target = os.readlink(path)
26- print("- type: link")
27- print(f" name: !!str {name}")
28- print(f" target: !!str {target}")
29- elif os.path.isdir(path):
30- print(f"- type: dir")
31- print(f" name: !!str {name}")
32- else:
33- print(f"- type: other")
34- print(f" name: !!str {name}")
35-
36-
37- def gather_store() -> None:
38- print("store:")
39- base = "/prog/pflotran/versions/.builds"
40- for name in os.listdir(base):
41- print(f"- !!str {name}")
42-
43-
44- def main() -> None:
45- gather_versions()
46- gather_store()
47-
48-
49- if __name__ == "__main__":
50- main()
51- """
52-
53-
54- class VersionsLinkType (BaseModel ):
55- type : Literal ["link" ]
56- name : str
57- target : str
58-
59-
60- class VersionsDirType (BaseModel ):
61- type : Literal ["dir" ]
62- name : str
6311
12+ class Collect (BaseModel ):
13+ unused_store_paths : set [str ]
6414
65- class VersionsOtherType (BaseModel ):
66- type : Literal ["other" ]
67- name : str
6815
16+ SCRIPT : bytes = (Path (__file__ ).parent / "_check.py" ).read_bytes ()
6917
70- class Collect (BaseModel ):
71- versions : list [VersionsLinkType | VersionsDirType | VersionsOtherType ] | None = None
72- store : list [str ] | None = None
7318
19+ async def collect (config : Config , area : AreaConfig ) -> Collect :
20+ base = Path (config .paths .system_base )
21+ store = base / config .paths .store
22+ versions = [base / env .dest for env in config .envs ]
7423
75- async def collect (area : AreaConfig ) -> Collect :
7624 proc = await asyncio .create_subprocess_exec (
7725 "ssh" ,
7826 "-T" ,
7927 area .host ,
80- "/usr/bin/env" ,
81- "python3" ,
28+ "/usr/bin/python3.6" ,
29+ "-" ,
30+ "--store" ,
31+ store ,
32+ "--versions" ,
33+ * versions ,
8234 stdin = asyncio .subprocess .PIPE ,
8335 stdout = asyncio .subprocess .PIPE ,
8436 stderr = asyncio .subprocess .PIPE ,
8537 )
86- stdout , stderr = await proc .communicate (COLLECTOR )
38+ stdout , stderr = await proc .communicate (SCRIPT )
8739
8840 print (f"Finished area { area .name } " )
8941
@@ -93,22 +45,34 @@ async def collect(area: AreaConfig) -> Collect:
9345async def _check (config : Config ) -> None :
9446 tasks : list [asyncio .Task [Collect ]] = []
9547
48+ if not config .areas :
49+ sys .exit ("No areas specified in config.yaml" )
50+
9651 for area in config .areas :
97- task = asyncio .create_task (collect (area ))
52+ task = asyncio .create_task (collect (config , area ))
9853 tasks .append (task )
9954
55+ collected : dict [str , Collect ] = {}
56+
10057 for area , info in zip (
10158 config .areas , await asyncio .gather (* tasks , return_exceptions = True )
10259 ):
103- print (f"--- { area .name } --- " )
60+ print (f"Processed { area .name } " )
10461 if isinstance (info , BaseException ):
10562 raise info
10663
107- for d in info .versions or []:
108- if isinstance (d , VersionsDirType ):
109- print (f" # { d .name } " )
110- elif isinstance (d , VersionsLinkType ):
111- print (f" - { d .name } -> { d .target } " )
64+ collected [area .name ] = info
65+
66+ all_areas = set (collected )
67+ all_unused_store_paths = set ()
68+ for c in collected .values ():
69+ all_unused_store_paths .update (c .unused_store_paths )
70+
71+ print ("Unused store paths:" )
72+ for path in sorted (all_unused_store_paths ):
73+ which = {k for k , v in collected .items () if path in v .unused_store_paths }
74+ which_str = "" if which == all_areas else ", " .join (which )
75+ print (f"{ path :<120} { which_str } " )
11276
11377
11478def do_check (config : Config ) -> None :
0 commit comments