Skip to content

Commit d5759de

Browse files
committed
vmupdate: improve waiting for apt-get update lock
"apt-get update" doesn't support waiting for other instances to finish, it exits immediately instead. With CLI apt-get version, it's possible to get it waiting externally (by taking the lock manually, and then make apt-get not try to lock it again). Unfortunately the same cannot be done for the API version, because there is no way (I can find) to disable locking in the apt.Cache.update() function. Workaround for missing feature https://bugs.debian.org/1069167
1 parent 1d8ebf9 commit d5759de

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

vmupdate/agent/source/apt/apt_cli.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import fcntl
2525
import os
26+
import contextlib
2627
from typing import List
2728

2829
from source.common.package_manager import PackageManager
@@ -38,12 +39,21 @@ def __init__(self, log_handler, log_level,):
3839
# to prevent a warning: `debconf: unable to initialize frontend: Dialog`
3940
os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
4041

41-
def wait_for_lock(self):
42+
@contextlib.contextmanager
43+
def apt_lock(self):
4244
"""
43-
Wait for any other apt-get instance to finish.
45+
Contex manager for locking compatible with 'apt-get update' lock.
4446
"""
4547
with open("/var/lib/apt/lists/lock", "rb+") as f_lock:
4648
fcntl.lockf(f_lock.fileno(), fcntl.LOCK_EX)
49+
yield
50+
51+
def wait_for_lock(self):
52+
"""
53+
Wait for any other apt-get instance to finish.
54+
"""
55+
with self.apt_lock():
56+
pass
4757

4858
def refresh(self, hard_fail: bool) -> ProcessResult:
4959
"""
@@ -52,9 +62,12 @@ def refresh(self, hard_fail: bool) -> ProcessResult:
5262
:param hard_fail: raise error if some repo is unavailable
5363
:return: (exit_code, stdout, stderr)
5464
"""
55-
self.wait_for_lock()
56-
cmd = [self.package_manager, "-q", "update"]
57-
result = self.run_cmd(cmd)
65+
# apply lock externally to wait for it, until
66+
# https://bugs.debian.org/1069167 gets implemented
67+
with self.apt_lock():
68+
cmd = [self.package_manager,
69+
"-o", "Debug::NoLocking=true", "-q", "update"]
70+
result = self.run_cmd(cmd)
5871
# 'apt-get update' reports error with exit code 100, but updater as a
5972
# whole reserves it for "no updates"
6073
if result.code == 100:

0 commit comments

Comments
 (0)