mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
Merge pull request #976 from jrdnbradford/add-conf-lockfile
Add TLJH config lockfile
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
filelock
|
||||||
packaging
|
packaging
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
filelock
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
pytest-asyncio
|
pytest-asyncio
|
||||||
|
|||||||
109
tljh/config.py
109
tljh/config.py
@@ -178,12 +178,7 @@ def show_config(config_path):
|
|||||||
"""
|
"""
|
||||||
Pretty print config from given config_path
|
Pretty print config from given config_path
|
||||||
"""
|
"""
|
||||||
try:
|
config = get_current_config(config_path)
|
||||||
with open(config_path) as f:
|
|
||||||
config = yaml.load(f)
|
|
||||||
except FileNotFoundError:
|
|
||||||
config = {}
|
|
||||||
|
|
||||||
yaml.dump(config, sys.stdout)
|
yaml.dump(config, sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
@@ -191,75 +186,105 @@ def set_config_value(config_path, key_path, value, validate=True):
|
|||||||
"""
|
"""
|
||||||
Set key at key_path in config_path to value
|
Set key at key_path in config_path to value
|
||||||
"""
|
"""
|
||||||
# FIXME: Have a file lock here
|
from filelock import FileLock, Timeout
|
||||||
|
|
||||||
|
lock_file = f"{config_path}.lock"
|
||||||
|
lock = FileLock(lock_file)
|
||||||
try:
|
try:
|
||||||
with open(config_path) as f:
|
with lock.acquire(timeout=1):
|
||||||
config = yaml.load(f)
|
config = get_current_config(config_path)
|
||||||
except FileNotFoundError:
|
config = set_item_in_config(config, key_path, value)
|
||||||
config = {}
|
validate_config(config, validate)
|
||||||
config = set_item_in_config(config, key_path, value)
|
|
||||||
|
|
||||||
validate_config(config, validate)
|
with open(config_path, "w") as f:
|
||||||
|
yaml.dump(config, f)
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
except Timeout:
|
||||||
yaml.dump(config, f)
|
print(f"Another instance of tljh-config holds the lock {lock_file}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def unset_config_value(config_path, key_path, validate=True):
|
def unset_config_value(config_path, key_path, validate=True):
|
||||||
"""
|
"""
|
||||||
Unset key at key_path in config_path
|
Unset key at key_path in config_path
|
||||||
"""
|
"""
|
||||||
# FIXME: Have a file lock here
|
from filelock import FileLock, Timeout
|
||||||
|
|
||||||
|
lock_file = f"{config_path}.lock"
|
||||||
|
lock = FileLock(lock_file)
|
||||||
try:
|
try:
|
||||||
with open(config_path) as f:
|
with lock.acquire(timeout=1):
|
||||||
config = yaml.load(f)
|
config = get_current_config(config_path)
|
||||||
except FileNotFoundError:
|
config = unset_item_from_config(config, key_path)
|
||||||
config = {}
|
validate_config(config, validate)
|
||||||
|
|
||||||
config = unset_item_from_config(config, key_path)
|
with open(config_path, "w") as f:
|
||||||
validate_config(config, validate)
|
yaml.dump(config, f)
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
except Timeout:
|
||||||
yaml.dump(config, f)
|
print(f"Another instance of tljh-config holds the lock {lock_file}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def add_config_value(config_path, key_path, value, validate=True):
|
def add_config_value(config_path, key_path, value, validate=True):
|
||||||
"""
|
"""
|
||||||
Add value to list at key_path
|
Add value to list at key_path
|
||||||
"""
|
"""
|
||||||
# FIXME: Have a file lock here
|
from filelock import FileLock, Timeout
|
||||||
|
|
||||||
|
lock_file = f"{config_path}.lock"
|
||||||
|
lock = FileLock(lock_file)
|
||||||
try:
|
try:
|
||||||
with open(config_path) as f:
|
with lock.acquire(timeout=1):
|
||||||
config = yaml.load(f)
|
config = get_current_config(config_path)
|
||||||
except FileNotFoundError:
|
config = add_item_to_config(config, key_path, value)
|
||||||
config = {}
|
validate_config(config, validate)
|
||||||
|
|
||||||
config = add_item_to_config(config, key_path, value)
|
with open(config_path, "w") as f:
|
||||||
validate_config(config, validate)
|
yaml.dump(config, f)
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
except Timeout:
|
||||||
yaml.dump(config, f)
|
print(f"Another instance of tljh-config holds the lock {lock_file}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def remove_config_value(config_path, key_path, value, validate=True):
|
def remove_config_value(config_path, key_path, value, validate=True):
|
||||||
"""
|
"""
|
||||||
Remove value from list at key_path
|
Remove value from list at key_path
|
||||||
"""
|
"""
|
||||||
# FIXME: Have a file lock here
|
from filelock import FileLock, Timeout
|
||||||
|
|
||||||
|
lock_file = f"{config_path}.lock"
|
||||||
|
lock = FileLock(lock_file)
|
||||||
|
try:
|
||||||
|
with lock.acquire(timeout=1):
|
||||||
|
config = get_current_config(config_path)
|
||||||
|
config = remove_item_from_config(config, key_path, value)
|
||||||
|
validate_config(config, validate)
|
||||||
|
|
||||||
|
with open(config_path, "w") as f:
|
||||||
|
yaml.dump(config, f)
|
||||||
|
|
||||||
|
except Timeout:
|
||||||
|
print(f"Another instance of tljh-config holds the lock {lock_file}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_config(config_path):
|
||||||
|
"""
|
||||||
|
Retrieve the current config at config_path
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
with open(config_path) as f:
|
with open(config_path) as f:
|
||||||
config = yaml.load(f)
|
return yaml.load(f)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
config = {}
|
return {}
|
||||||
|
|
||||||
config = remove_item_from_config(config, key_path, value)
|
|
||||||
validate_config(config, validate)
|
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
|
||||||
yaml.dump(config, f)
|
|
||||||
|
|
||||||
|
|
||||||
def check_hub_ready():
|
def check_hub_ready():
|
||||||
|
"""
|
||||||
|
Checks that hub is running.
|
||||||
|
"""
|
||||||
from .configurer import load_config
|
from .configurer import load_config
|
||||||
|
|
||||||
base_url = load_config()["base_url"]
|
base_url = load_config()["base_url"]
|
||||||
|
|||||||
@@ -26,3 +26,6 @@ jupyterhub-idle-culler>=1.2.1,<2
|
|||||||
# ref: https://github.com/jupyterhub/the-littlest-jupyterhub/issues/289
|
# ref: https://github.com/jupyterhub/the-littlest-jupyterhub/issues/289
|
||||||
#
|
#
|
||||||
pycurl>=7.45.2,<8
|
pycurl>=7.45.2,<8
|
||||||
|
|
||||||
|
# filelock is used to help us do atomic operations on config file(s)
|
||||||
|
filelock>=3.15.4,<4
|
||||||
|
|||||||
Reference in New Issue
Block a user