18
18
import sys
19
19
import time
20
20
from collections .abc import Mapping , Sequence
21
+ from contextlib import contextmanager
21
22
from copy import deepcopy
22
23
23
24
import requests
25
+ from filelock import FileLock , Timeout
24
26
25
27
from .yaml import yaml
26
28
32
34
CONFIG_FILE = os .path .join (CONFIG_DIR , "config.yaml" )
33
35
34
36
37
+ @contextmanager
38
+ def config_file_lock (config_path , timeout = 1 ):
39
+ """Context manager to acquire the config file lock"""
40
+ lock_file = f"{ config_path } .lock"
41
+ try :
42
+ with FileLock (lock_file ).acquire (timeout = timeout ):
43
+ yield
44
+
45
+ except Timeout :
46
+ print (
47
+ f"Another instance of tljh-config holds the lock { lock_file } ." ,
48
+ file = sys .stderr ,
49
+ )
50
+ sys .exit (1 )
51
+
52
+
35
53
def set_item_in_config (config , property_path , value ):
36
54
"""
37
55
Set key at property_path to value in config & return new config.
@@ -169,9 +187,10 @@ def validate_config(config, validate):
169
187
print (
170
188
f"Config validation error: { e .message } .\n "
171
189
"You can still apply this change without validation by re-running your command with the --no-validate flag.\n "
172
- "If you think this validation error is incorrect, please report it to https://github.com/jupyterhub/the-littlest-jupyterhub/issues."
190
+ "If you think this validation error is incorrect, please report it to https://github.com/jupyterhub/the-littlest-jupyterhub/issues." ,
191
+ file = sys .stderr ,
173
192
)
174
- exit ()
193
+ sys . exit (1 )
175
194
176
195
177
196
def show_config (config_path ):
@@ -186,88 +205,52 @@ def set_config_value(config_path, key_path, value, validate=True):
186
205
"""
187
206
Set key at key_path in config_path to value
188
207
"""
189
- from filelock import FileLock , Timeout
208
+ with config_file_lock (config_path ):
209
+ config = get_current_config (config_path )
210
+ config = set_item_in_config (config , key_path , value )
211
+ validate_config (config , validate )
190
212
191
- lock_file = f"{ config_path } .lock"
192
- lock = FileLock (lock_file )
193
- try :
194
- with lock .acquire (timeout = 1 ):
195
- config = get_current_config (config_path )
196
- config = set_item_in_config (config , key_path , value )
197
- validate_config (config , validate )
198
-
199
- with open (config_path , "w" ) as f :
200
- yaml .dump (config , f )
201
-
202
- except Timeout :
203
- print (f"Another instance of tljh-config holds the lock { lock_file } " )
204
- exit (1 )
213
+ with open (config_path , "w" ) as f :
214
+ yaml .dump (config , f )
205
215
206
216
207
217
def unset_config_value (config_path , key_path , validate = True ):
208
218
"""
209
219
Unset key at key_path in config_path
210
220
"""
211
- from filelock import FileLock , Timeout
221
+ with config_file_lock (config_path ):
222
+ config = get_current_config (config_path )
223
+ config = unset_item_from_config (config , key_path )
224
+ validate_config (config , validate )
212
225
213
- lock_file = f"{ config_path } .lock"
214
- lock = FileLock (lock_file )
215
- try :
216
- with lock .acquire (timeout = 1 ):
217
- config = get_current_config (config_path )
218
- config = unset_item_from_config (config , key_path )
219
- validate_config (config , validate )
220
-
221
- with open (config_path , "w" ) as f :
222
- yaml .dump (config , f )
223
-
224
- except Timeout :
225
- print (f"Another instance of tljh-config holds the lock { lock_file } " )
226
- exit (1 )
226
+ with open (config_path , "w" ) as f :
227
+ yaml .dump (config , f )
227
228
228
229
229
230
def add_config_value (config_path , key_path , value , validate = True ):
230
231
"""
231
232
Add value to list at key_path
232
233
"""
233
- from filelock import FileLock , Timeout
234
+ with config_file_lock (config_path ):
235
+ config = get_current_config (config_path )
236
+ config = add_item_to_config (config , key_path , value )
237
+ validate_config (config , validate )
234
238
235
- lock_file = f"{ config_path } .lock"
236
- lock = FileLock (lock_file )
237
- try :
238
- with lock .acquire (timeout = 1 ):
239
- config = get_current_config (config_path )
240
- config = add_item_to_config (config , key_path , value )
241
- validate_config (config , validate )
242
-
243
- with open (config_path , "w" ) as f :
244
- yaml .dump (config , f )
245
-
246
- except Timeout :
247
- print (f"Another instance of tljh-config holds the lock { lock_file } " )
248
- exit (1 )
239
+ with open (config_path , "w" ) as f :
240
+ yaml .dump (config , f )
249
241
250
242
251
243
def remove_config_value (config_path , key_path , value , validate = True ):
252
244
"""
253
245
Remove value from list at key_path
254
246
"""
255
- from filelock import FileLock , Timeout
247
+ with config_file_lock (config_path ):
248
+ config = get_current_config (config_path )
249
+ config = remove_item_from_config (config , key_path , value )
250
+ validate_config (config , validate )
256
251
257
- lock_file = f"{ config_path } .lock"
258
- lock = FileLock (lock_file )
259
- try :
260
- with lock .acquire (timeout = 1 ):
261
- config = get_current_config (config_path )
262
- config = remove_item_from_config (config , key_path , value )
263
- validate_config (config , validate )
264
-
265
- with open (config_path , "w" ) as f :
266
- yaml .dump (config , f )
267
-
268
- except Timeout :
269
- print (f"Another instance of tljh-config holds the lock { lock_file } " )
270
- exit (1 )
252
+ with open (config_path , "w" ) as f :
253
+ yaml .dump (config , f )
271
254
272
255
273
256
def get_current_config (config_path ):
0 commit comments