diff options
| author | Oleksandr Kuchmystyi <o.kuchmystyi@vyos.io> | 2026-02-24 15:12:44 +0300 |
|---|---|---|
| committer | Oleksandr Kuchmystyi <o.kuchmystyi@vyos.io> | 2026-02-25 10:35:55 +0300 |
| commit | e8c6a8f37470416e72a26fbbdfad24f8dcea7208 (patch) | |
| tree | 45b563d25a7d0f8035ad87fad21038b388c461ee /python | |
| parent | 662b45c159393aa9451c93b168da415021949857 (diff) | |
| download | vyos-1x-e8c6a8f37470416e72a26fbbdfad24f8dcea7208.tar.gz vyos-1x-e8c6a8f37470416e72a26fbbdfad24f8dcea7208.zip | |
vpp: T8297: Fixed double enabling of VPP
When trying to configure the VPP interface using `set vpp settings interface eth0`
and `commit`, user first see a success. Upon repeating the configuration after
deleting and re-adding it, the commit fails with an error:
- `FileExistsError: Cannot open locked storage: /run/vpp/vpp_conf.json`
This indicates that another process is using the file or a previous operation did not
release the lock, preventing new changes from being written.
The commit adds context manager support and safe close to `JSONStorage`
and refactor VPP config handling.
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/vpp/configdb.py | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/python/vyos/vpp/configdb.py b/python/vyos/vpp/configdb.py index 13c1cd3a0..e86b32fb7 100644 --- a/python/vyos/vpp/configdb.py +++ b/python/vyos/vpp/configdb.py @@ -34,6 +34,10 @@ class JSONStorage: """ # If a name is not provided, this is a temporary one-time storage # this use case is strange, but let's allow this + + # Indicates that the object has already been closed and cannot be used again + self.__closed = False + if not name: self.__temporary = True self.__cache: dict[Any, Any] = {} @@ -68,17 +72,34 @@ class JSONStorage: self.__cache = self.__load_file() def __del__(self) -> None: + self.close() + + def __enter__(self): + return self + + def __exit__(self, *exc): + self.close() + + def close(self): """Dump data to persistent storage and unlock it""" - if self.__temporary: + + # Do not do anything if it is already closed storage + if self.__closed: return - # dump a cache to storage - if self.__cache: - self.__dump_file() - # or remove a file - else: - self.__storage.unlink() - # unlock a storage - self.__lock_file.unlink() + + try: + if self.__temporary: + return + # dump a cache to storage + if self.__cache: + self.__dump_file() + # or remove a file + else: + self.__storage.unlink(missing_ok=True) + # unlock a storage + self.__lock_file.unlink(missing_ok=True) + finally: + self.__closed = True def __check_types(self, data: Any) -> None: """Check if all the data have supported types |
