-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscripts_checker.py
More file actions
117 lines (90 loc) · 3.81 KB
/
scripts_checker.py
File metadata and controls
117 lines (90 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import concurrent.futures
import os
import sys
# noinspection PyUnresolvedReferences
# Workaround for AttributeError when concurrent.futures.thread._threads_queues.clear()
import git
import win32wnet
# noinspection PyUnresolvedReferences
from win32wnet import error as PywintypesError
REMOTE_URL = "https://github.com/ISISNeutronMuon/InstrumentScripts"
class MissingEnvironmentVariable(KeyError):
"""
Raised when accessed an environment variable that does not exist.
"""
def __init__(self, err_msg):
super().__init__(err_msg)
def _get_env_var(var_name):
"""
Return the value of environment variable with given name, or raise an exception if it doesn't exist.
"""
var = os.environ.get(var_name)
if var is None:
raise MissingEnvironmentVariable(
f'Tried accessing environment variable "{var_name}" that does not exist'
)
return var
def ls_remote(url):
"""
List references in the remote repository.
"""
remote_refs = {}
g = git.cmd.Git()
for ref in g.ls_remote(url).split("\n"):
hash_ref_list = ref.split("\t")
remote_refs[hash_ref_list[1]] = hash_ref_list[0]
return remote_refs
remote_head = ls_remote(REMOTE_URL)["HEAD"] # Get the remote master HEAD commit ID
# inst_hostnames = [inst['hostName'] for inst in ChannelAccessUtils().get_inst_list()]
inst_hostnames = ["NDXMAPS"]
different_head, multiple_repos, cannot_connect = [], [], []
def check_inst_scripts(hostname):
scripts_path = f"\\\\{hostname}\\InstScripts$"
# Connect to the instrument shared network resource
username = f'{hostname}\\{_get_env_var("INSTRUMENT_SCRIPTS_CREDENTIALS_USR")}'
password = _get_env_var("INSTRUMENT_SCRIPTS_CREDENTIALS_PSW")
try:
# dwType, lpLocalName, lpRemoteName[, lpProviderName, Username, Password, flags]
# noinspection PyArgumentList
win32wnet.WNetAddConnection2(0, None, scripts_path, None, username, password)
except PywintypesError as e:
sys.stderr.write(f"Error {e.winerror} connecting to {hostname}: {e.strerror}\n")
cannot_connect.append(hostname)
return
repo = git.Repo(path=scripts_path)
if len(repo.remotes) > 1:
print(f'WARNING: {hostname} has multiple remote repositories: \n{repo.git.remote("-v")}\n')
multiple_repos.append(hostname)
current_head = repo.head.commit.hexsha
if current_head != remote_head:
print(
f'WARNING: {hostname} HEAD with commit ID "{current_head}" '
f'is different from remote master HEAD with commit ID "{remote_head}".'
)
different_head.append(hostname)
return hostname
def check_all_scripts(hostnames):
print("Starting instrument script checker")
with concurrent.futures.ThreadPoolExecutor(max_workers=32) as executor:
futures = [executor.submit(check_inst_scripts, hostname) for hostname in hostnames]
try:
results = [future.result() for future in concurrent.futures.as_completed(futures)]
except KeyboardInterrupt:
# noinspection PyProtectedMember
executor._threads.clear()
# noinspection PyProtectedMember, PyUnresolvedReferences
concurrent.futures.thread._threads_queues.clear()
raise
inst_whose_head_not_master = [x for x in results if x is not None]
return inst_whose_head_not_master
# Manual running (for the time being)
print(check_all_scripts(inst_hostnames))
connected = set(inst_hostnames) ^ set(cannot_connect)
print(f"Checked {len(connected)} instruments out of {len(inst_hostnames)}.")
print(f"Not on master HEAD: {different_head}")
print(f"Multiple repositories: {multiple_repos}")
print(f"Could not connect to: {cannot_connect}")
if len(different_head) + len(multiple_repos) + len(cannot_connect) > 0:
sys.exit(1)
else:
sys.exit(0)