move file locking into a utility module with logging
This commit is contained in:
parent
5edfddabf5
commit
adb8e2ac43
|
@ -14,7 +14,6 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import asyncio
|
||||
import fcntl
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
@ -134,9 +133,7 @@ class FilesystemController(SubiquityController):
|
|||
|
||||
async def _probe(self):
|
||||
with self.context.child("_probe") as context:
|
||||
await run_in_thread(
|
||||
fcntl.flock, self.app.install_lock_file, fcntl.LOCK_SH)
|
||||
try:
|
||||
async with self.app.install_lock_file.shared():
|
||||
self._crash_reports = {}
|
||||
if isinstance(self.ui.body, ProbingFailed):
|
||||
self.ui.set_body(SlowProbing(self))
|
||||
|
@ -166,8 +163,6 @@ class FilesystemController(SubiquityController):
|
|||
self._crash_reports[restricted] = report
|
||||
continue
|
||||
break
|
||||
finally:
|
||||
fcntl.flock(self.app.install_lock_file, fcntl.LOCK_UN)
|
||||
|
||||
def convert_autoinstall_config(self):
|
||||
log.debug("self.ai_data = %s", self.ai_data)
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
import asyncio
|
||||
import contextlib
|
||||
import datetime
|
||||
import fcntl
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
@ -281,13 +280,9 @@ class InstallProgressController(SubiquityController):
|
|||
|
||||
log.debug('curtin install cmd: {}'.format(curtin_cmd))
|
||||
|
||||
await run_in_thread(
|
||||
fcntl.flock, self.app.install_lock_file, fcntl.LOCK_EX)
|
||||
try:
|
||||
async with self.app.install_lock_file.exclusive():
|
||||
cp = await arun_command(
|
||||
self.logged_command(curtin_cmd), check=True)
|
||||
finally:
|
||||
fcntl.flock(self.app.install_lock_file, fcntl.LOCK_UN)
|
||||
|
||||
log.debug('curtin_install completed: %s', cp.returncode)
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ from subiquitycore.core import Application
|
|||
from subiquity.controllers.error import (
|
||||
ErrorReportKind,
|
||||
)
|
||||
from subiquity.lockfile import Lockfile
|
||||
from subiquity.models.subiquity import SubiquityModel
|
||||
from subiquity.snapd import (
|
||||
AsyncSnapd,
|
||||
|
@ -123,7 +124,7 @@ class Subiquity(Application):
|
|||
self.controllers.remove("Zdev")
|
||||
|
||||
super().__init__(opts)
|
||||
self.install_lock_file = open(self.state_path("installing"), 'w')
|
||||
self.install_lock_file = Lockfile(self.state_path("installing"))
|
||||
self.block_log_dir = block_log_dir
|
||||
self.kernel_cmdline = shlex.split(opts.kernel_cmdline)
|
||||
if opts.snaps_from_examples:
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
# Copyright 2020 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import fcntl
|
||||
import logging
|
||||
|
||||
from subiquitycore.async_helpers import run_in_thread
|
||||
|
||||
log = logging.getLogger('subiquity.lockfile')
|
||||
|
||||
|
||||
class _LockContext:
|
||||
|
||||
def __init__(self, lockfile, flags):
|
||||
self.lockfile = lockfile
|
||||
self.flags = flags
|
||||
self._kind = "???"
|
||||
if flags & fcntl.LOCK_EX:
|
||||
self._kind = "exclusive"
|
||||
elif flags & fcntl.LOCK_SH:
|
||||
self._kind = "shared"
|
||||
|
||||
def __enter__(self):
|
||||
log.debug("locking %s %s", self._kind, self.lockfile.path)
|
||||
fcntl.flock(self.lockfile.fp, self.flags)
|
||||
return self
|
||||
|
||||
async def __aenter__(self):
|
||||
return await run_in_thread(self.__enter__)
|
||||
|
||||
def __exit__(self, etype, evalue, etb):
|
||||
log.debug("unlocking %s %s", self._kind, self.lockfile.path)
|
||||
fcntl.flock(self.lockfile.fp, fcntl.LOCK_UN)
|
||||
|
||||
async def __aexit__(self, etype, evalue, etb):
|
||||
self.__exit__(etype, evalue, etb)
|
||||
|
||||
|
||||
class Lockfile:
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.fp = open(path, 'w')
|
||||
|
||||
def exclusive(self):
|
||||
return _LockContext(self, fcntl.LOCK_EX)
|
||||
|
||||
def shared(self):
|
||||
return _LockContext(self, fcntl.LOCK_SH)
|
Loading…
Reference in New Issue