nodeocc 1.0.10__tar.gz → 1.0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nodeocc-1.0.10 → nodeocc-1.0.12}/PKG-INFO +1 -1
- {nodeocc-1.0.10 → nodeocc-1.0.12}/pyproject.toml +1 -1
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/controller/controller.py +12 -10
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/nodeocc.egg-info/PKG-INFO +1 -1
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/view/curses_multiwindow.py +31 -9
- {nodeocc-1.0.10 → nodeocc-1.0.12}/README.md +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/setup.cfg +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/setup.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/__init__.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/model/infrastructure.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/model/job.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/nodeocc.egg-info/SOURCES.txt +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/nodeocc.egg-info/dependency_links.txt +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/nodeocc.egg-info/entry_points.txt +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/nodeocc.egg-info/requires.txt +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/nodeocc.egg-info/top_level.txt +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/readers/compute_wait_time.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/readers/slurmreader.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/view/__init__.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/view/slurm_list.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/view/slurm_viz.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/view/styles.py +0 -0
- {nodeocc-1.0.10 → nodeocc-1.0.12}/src/view/utils.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nodeocc"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.12"
|
|
8
8
|
authors = [{ name = "Matteo Boschini" }]
|
|
9
9
|
maintainers = [{ name = "Lorenzo Bonicelli" }, { name = "Aniello Panariello" }]
|
|
10
10
|
description = "TUI application for viewing the status of GPU allocations on a Slurm cluster"
|
|
@@ -60,7 +60,6 @@ except Exception as e:
|
|
|
60
60
|
newest_version = '?.?.?'
|
|
61
61
|
time.sleep(5)
|
|
62
62
|
|
|
63
|
-
|
|
64
63
|
BEGIN_DELIM = "!{$"
|
|
65
64
|
END_DELIM_ENCODED = "!}$".encode('utf-8')
|
|
66
65
|
EXTRA_MSG_BEGIN_DELIM = "!{#"
|
|
@@ -81,13 +80,17 @@ assert os.access(args.basepath, os.R_OK), f"Base path {args.basepath} not readab
|
|
|
81
80
|
# export args
|
|
82
81
|
orig_instance = Singleton.getInstance(args)
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
try:
|
|
84
|
+
last_update = os.path.getmtime(conf_path + "/view/slurm_viz.py")
|
|
85
|
+
if os.path.getmtime(conf_path + "/view/slurm_list.py") > last_update:
|
|
86
|
+
last_update = os.path.getmtime(conf_path + "/view/slurm_list.py")
|
|
87
|
+
if os.path.getmtime(conf_path + "/view/styles.py") > last_update:
|
|
88
|
+
last_update = os.path.getmtime(conf_path + "/view/styles.py")
|
|
89
|
+
if os.path.getmtime(conf_path + "/readers/slurmreader.py") > last_update:
|
|
90
|
+
last_update = os.path.getmtime(conf_path + "/readers/slurmreader.py")
|
|
91
|
+
except Exception as e:
|
|
92
|
+
orig_instance.err(f"Could not get last update time: {e}")
|
|
93
|
+
last_update = time.time()
|
|
91
94
|
|
|
92
95
|
|
|
93
96
|
def get_avg_wait_time(instance: Singleton):
|
|
@@ -301,8 +304,7 @@ def _main():
|
|
|
301
304
|
wrapper(display_main)
|
|
302
305
|
|
|
303
306
|
|
|
304
|
-
|
|
305
|
-
_main()
|
|
307
|
+
_main()
|
|
306
308
|
|
|
307
309
|
orig_instance.cleanup()
|
|
308
310
|
exit(0)
|
|
@@ -13,6 +13,7 @@ import traceback
|
|
|
13
13
|
from logging.handlers import RotatingFileHandler
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from view import update_views
|
|
16
|
+
import stat
|
|
16
17
|
|
|
17
18
|
a_filter_values = [None, 'me', 'prod', 'stud', 'cvcs']
|
|
18
19
|
|
|
@@ -35,6 +36,14 @@ BUTTON_ACTIONS = {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
|
|
39
|
+
def is_file_writable_byall(file_path):
|
|
40
|
+
return os.stat(file_path).st_mode & stat.S_IWOTH
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def is_file_readable_byall(file_path):
|
|
44
|
+
return os.stat(file_path).st_mode & stat.S_IROTH
|
|
45
|
+
|
|
46
|
+
|
|
38
47
|
def try_open_socket_as_slave(instance):
|
|
39
48
|
if not instance.port_file_exists():
|
|
40
49
|
raise Exception("No master running")
|
|
@@ -89,7 +98,7 @@ class Singleton:
|
|
|
89
98
|
|
|
90
99
|
def clean_port_files(self):
|
|
91
100
|
for f in os.listdir(self.basepath):
|
|
92
|
-
if f.endswith('.port'):
|
|
101
|
+
if f.endswith('.port') and is_file_writable_byall(os.path.join(self.basepath, f)):
|
|
93
102
|
os.system(f"rm {os.path.join(self.basepath, f)}")
|
|
94
103
|
|
|
95
104
|
def __init__(self, args=None):
|
|
@@ -99,6 +108,9 @@ class Singleton:
|
|
|
99
108
|
else:
|
|
100
109
|
Singleton.__instance = self
|
|
101
110
|
|
|
111
|
+
self.args = args
|
|
112
|
+
self.setup_logging()
|
|
113
|
+
|
|
102
114
|
self.try_open_counter = 0
|
|
103
115
|
self.voff = 0
|
|
104
116
|
self.mouse_state = {}
|
|
@@ -110,7 +122,6 @@ class Singleton:
|
|
|
110
122
|
self.fetch_fn = None
|
|
111
123
|
self.view_mode = 'gpu'
|
|
112
124
|
self.job_id_type = 'agg'
|
|
113
|
-
self.args = args
|
|
114
125
|
|
|
115
126
|
self.show_account = False
|
|
116
127
|
self.show_prio = False
|
|
@@ -147,8 +158,6 @@ class Singleton:
|
|
|
147
158
|
|
|
148
159
|
self.is_master = not self.check_existing_master_running()
|
|
149
160
|
|
|
150
|
-
self.setup_logging()
|
|
151
|
-
|
|
152
161
|
if self.is_master:
|
|
153
162
|
# clean up old port files
|
|
154
163
|
self.clean_port_files()
|
|
@@ -158,8 +167,11 @@ class Singleton:
|
|
|
158
167
|
|
|
159
168
|
def get_port_file_name(self):
|
|
160
169
|
if self.port_file_exists():
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
portfiles = [f for f in os.listdir(self.basepath) if f.endswith('.port')]
|
|
171
|
+
portfiles = [(f, os.path.join(self.basepath, f)) for f in portfiles]
|
|
172
|
+
portfiles = [(fname, fpath) for fname, fpath in portfiles if is_file_readable_byall(fpath) and is_file_writable_byall(fpath)][0]
|
|
173
|
+
|
|
174
|
+
return portfiles[0], portfiles[1]
|
|
163
175
|
return None
|
|
164
176
|
|
|
165
177
|
def check_existing_master_running(self):
|
|
@@ -171,7 +183,15 @@ class Singleton:
|
|
|
171
183
|
return False
|
|
172
184
|
|
|
173
185
|
def port_file_exists(self):
|
|
174
|
-
|
|
186
|
+
"""
|
|
187
|
+
Check if a port file exists in the basepath and the file has 666 permissions
|
|
188
|
+
"""
|
|
189
|
+
portfiles = [f for f in os.listdir(self.basepath) if f.endswith('.port')]
|
|
190
|
+
if len(portfiles) == 0:
|
|
191
|
+
return False
|
|
192
|
+
portfiles = [os.path.join(self.basepath, f) for f in portfiles]
|
|
193
|
+
portfiles = [f for f in portfiles if is_file_readable_byall(f) and is_file_writable_byall(f)]
|
|
194
|
+
return len(portfiles) > 0
|
|
175
195
|
|
|
176
196
|
def create_socket_as_master(self):
|
|
177
197
|
# create udp socket for broadcasting
|
|
@@ -191,8 +211,10 @@ class Singleton:
|
|
|
191
211
|
# get pid of current process
|
|
192
212
|
self.pid = os.getpid()
|
|
193
213
|
|
|
194
|
-
# create file to store port
|
|
195
|
-
Path(self.basepath, f'{self.port}.port')
|
|
214
|
+
# create file to store port with 666 permissions to file
|
|
215
|
+
filepath = Path(self.basepath, f'{self.port}.port')
|
|
216
|
+
filepath.write_text(str(self.pid))
|
|
217
|
+
os.chmod(filepath, 0o666)
|
|
196
218
|
|
|
197
219
|
return self.port
|
|
198
220
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|