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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import fcntl
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -134,9 +133,7 @@ class FilesystemController(SubiquityController):
|
||||||
|
|
||||||
async def _probe(self):
|
async def _probe(self):
|
||||||
with self.context.child("_probe") as context:
|
with self.context.child("_probe") as context:
|
||||||
await run_in_thread(
|
async with self.app.install_lock_file.shared():
|
||||||
fcntl.flock, self.app.install_lock_file, fcntl.LOCK_SH)
|
|
||||||
try:
|
|
||||||
self._crash_reports = {}
|
self._crash_reports = {}
|
||||||
if isinstance(self.ui.body, ProbingFailed):
|
if isinstance(self.ui.body, ProbingFailed):
|
||||||
self.ui.set_body(SlowProbing(self))
|
self.ui.set_body(SlowProbing(self))
|
||||||
|
@ -166,8 +163,6 @@ class FilesystemController(SubiquityController):
|
||||||
self._crash_reports[restricted] = report
|
self._crash_reports[restricted] = report
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
finally:
|
|
||||||
fcntl.flock(self.app.install_lock_file, fcntl.LOCK_UN)
|
|
||||||
|
|
||||||
def convert_autoinstall_config(self):
|
def convert_autoinstall_config(self):
|
||||||
log.debug("self.ai_data = %s", self.ai_data)
|
log.debug("self.ai_data = %s", self.ai_data)
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import contextlib
|
import contextlib
|
||||||
import datetime
|
import datetime
|
||||||
import fcntl
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -281,13 +280,9 @@ class InstallProgressController(SubiquityController):
|
||||||
|
|
||||||
log.debug('curtin install cmd: {}'.format(curtin_cmd))
|
log.debug('curtin install cmd: {}'.format(curtin_cmd))
|
||||||
|
|
||||||
await run_in_thread(
|
async with self.app.install_lock_file.exclusive():
|
||||||
fcntl.flock, self.app.install_lock_file, fcntl.LOCK_EX)
|
|
||||||
try:
|
|
||||||
cp = await arun_command(
|
cp = await arun_command(
|
||||||
self.logged_command(curtin_cmd), check=True)
|
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)
|
log.debug('curtin_install completed: %s', cp.returncode)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ from subiquitycore.core import Application
|
||||||
from subiquity.controllers.error import (
|
from subiquity.controllers.error import (
|
||||||
ErrorReportKind,
|
ErrorReportKind,
|
||||||
)
|
)
|
||||||
|
from subiquity.lockfile import Lockfile
|
||||||
from subiquity.models.subiquity import SubiquityModel
|
from subiquity.models.subiquity import SubiquityModel
|
||||||
from subiquity.snapd import (
|
from subiquity.snapd import (
|
||||||
AsyncSnapd,
|
AsyncSnapd,
|
||||||
|
@ -123,7 +124,7 @@ class Subiquity(Application):
|
||||||
self.controllers.remove("Zdev")
|
self.controllers.remove("Zdev")
|
||||||
|
|
||||||
super().__init__(opts)
|
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.block_log_dir = block_log_dir
|
||||||
self.kernel_cmdline = shlex.split(opts.kernel_cmdline)
|
self.kernel_cmdline = shlex.split(opts.kernel_cmdline)
|
||||||
if opts.snaps_from_examples:
|
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