[unpackfs] Refactor mounting for an entry
- The entry knows where it should be mounted, and can remember that - mount_entry() didn't use self, so made no sense as a method of the Operation class
This commit is contained in:
parent
49a584377e
commit
7e4cb28c1c
@ -52,7 +52,8 @@ class UnpackEntry:
|
|||||||
:param sourcefs:
|
:param sourcefs:
|
||||||
:param destination:
|
:param destination:
|
||||||
"""
|
"""
|
||||||
__slots__ = ['source', 'sourcefs', 'destination', 'copied', 'total', 'exclude', 'excludeFile']
|
__slots__ = ['source', 'sourcefs', 'destination', 'copied', 'total', 'exclude', 'excludeFile',
|
||||||
|
'mountPoint']
|
||||||
|
|
||||||
def __init__(self, source, sourcefs, destination):
|
def __init__(self, source, sourcefs, destination):
|
||||||
"""
|
"""
|
||||||
@ -73,6 +74,7 @@ class UnpackEntry:
|
|||||||
self.excludeFile = None
|
self.excludeFile = None
|
||||||
self.copied = 0
|
self.copied = 0
|
||||||
self.total = 0
|
self.total = 0
|
||||||
|
self.mountPoint = None
|
||||||
|
|
||||||
def is_file(self):
|
def is_file(self):
|
||||||
return self.sourcefs == "file"
|
return self.sourcefs == "file"
|
||||||
@ -104,6 +106,39 @@ class UnpackEntry:
|
|||||||
self.total = len(fslist.splitlines())
|
self.total = len(fslist.splitlines())
|
||||||
return self.total
|
return self.total
|
||||||
|
|
||||||
|
def do_mount(self, base):
|
||||||
|
"""
|
||||||
|
Mount given @p entry as loop device underneath @p base
|
||||||
|
|
||||||
|
A *file* entry (e.g. one with *sourcefs* set to *file*)
|
||||||
|
is not mounted and just ignored.
|
||||||
|
|
||||||
|
:param entry: the entry to mount (source is the important property)
|
||||||
|
:param imgmountdir: where to mount it
|
||||||
|
|
||||||
|
:returns: None, but throws if the mount failed
|
||||||
|
"""
|
||||||
|
imgbasename = os.path.splitext(
|
||||||
|
os.path.basename(self.source))[0]
|
||||||
|
imgmountdir = os.path.join(base, imgbasename)
|
||||||
|
os.makedirs(imgmountdir, exist_ok=True)
|
||||||
|
|
||||||
|
# This is where it *would* go (files bail out before actually mounting)
|
||||||
|
self.mountPoint = imgmountdir
|
||||||
|
|
||||||
|
if self.is_file():
|
||||||
|
return
|
||||||
|
|
||||||
|
if os.path.isdir(self.source):
|
||||||
|
r = mount(self.source, imgmountdir, "", "--bind")
|
||||||
|
elif os.path.isfile(self.source):
|
||||||
|
r = mount(self.source, imgmountdir, self.sourcefs, "loop")
|
||||||
|
else: # self.source is a device
|
||||||
|
r = mount(self.source, imgmountdir, self.sourcefs, "")
|
||||||
|
|
||||||
|
if r != 0:
|
||||||
|
raise subprocess.CalledProcessError(r, "mount")
|
||||||
|
|
||||||
|
|
||||||
ON_POSIX = 'posix' in sys.builtin_module_names
|
ON_POSIX = 'posix' in sys.builtin_module_names
|
||||||
|
|
||||||
@ -260,17 +295,11 @@ class UnpackOperation:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for entry in self.entries:
|
for entry in self.entries:
|
||||||
imgbasename = os.path.splitext(
|
entry.do_mount(source_mount_path)
|
||||||
os.path.basename(entry.source))[0]
|
|
||||||
imgmountdir = os.path.join(source_mount_path, imgbasename)
|
|
||||||
os.makedirs(imgmountdir, exist_ok=True)
|
|
||||||
|
|
||||||
self.mount_image(entry, imgmountdir)
|
|
||||||
|
|
||||||
entry.do_count(imgmountdir) # Fill in the entry.total
|
entry.do_count(imgmountdir) # Fill in the entry.total
|
||||||
|
|
||||||
self.report_progress()
|
self.report_progress()
|
||||||
error_msg = self.unpack_image(entry, imgmountdir)
|
error_msg = self.unpack_image(entry, entry.mountPoint)
|
||||||
|
|
||||||
if error_msg:
|
if error_msg:
|
||||||
return (_("Failed to unpack image \"{}\"").format(entry.source),
|
return (_("Failed to unpack image \"{}\"").format(entry.source),
|
||||||
@ -280,31 +309,6 @@ class UnpackOperation:
|
|||||||
finally:
|
finally:
|
||||||
shutil.rmtree(source_mount_path, ignore_errors=True, onerror=None)
|
shutil.rmtree(source_mount_path, ignore_errors=True, onerror=None)
|
||||||
|
|
||||||
def mount_image(self, entry, imgmountdir):
|
|
||||||
"""
|
|
||||||
Mount given @p entry as loop device on @p imgmountdir.
|
|
||||||
|
|
||||||
A *file* entry (e.g. one with *sourcefs* set to *file*)
|
|
||||||
is not mounted and just ignored.
|
|
||||||
|
|
||||||
:param entry: the entry to mount (source is the important property)
|
|
||||||
:param imgmountdir: where to mount it
|
|
||||||
|
|
||||||
:returns: None, but throws if the mount failed
|
|
||||||
"""
|
|
||||||
if entry.is_file():
|
|
||||||
return
|
|
||||||
|
|
||||||
if os.path.isdir(entry.source):
|
|
||||||
r = mount(entry.source, imgmountdir, "", "--bind")
|
|
||||||
elif os.path.isfile(entry.source):
|
|
||||||
r = mount(entry.source, imgmountdir, entry.sourcefs, "loop")
|
|
||||||
else: # entry.source is a device
|
|
||||||
r = mount(entry.source, imgmountdir, entry.sourcefs, "")
|
|
||||||
|
|
||||||
if r != 0:
|
|
||||||
raise subprocess.CalledProcessError(r, "mount")
|
|
||||||
|
|
||||||
|
|
||||||
def unpack_image(self, entry, imgmountdir):
|
def unpack_image(self, entry, imgmountdir):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user