Merge branch 'issue-1188'

FIXES #1181
FIXES #1188

You can now copy single files from the source image to the target.
You can now copy directories from the source image to the target.
This commit is contained in:
Adriaan de Groot 2019-09-30 17:35:53 +02:00
commit 8dc91b9838
2 changed files with 80 additions and 20 deletions

View File

@ -58,6 +58,9 @@ class UnpackEntry:
self.copied = 0
self.total = 0
def is_file(self):
return self.sourcefs == "file"
ON_POSIX = 'posix' in sys.builtin_module_names
@ -100,7 +103,7 @@ def file_copy(source, dest, progress_cb):
# `source` *must* end with '/' otherwise a directory named after the source
# will be created in `dest`: ie if `source` is "/foo/bar" and `dest` is
# "/dest", then files will be copied in "/dest/bar".
if not source.endswith("/"):
if not source.endswith("/") and not os.path.isfile(source):
source += "/"
num_files_total_local = 0
@ -225,11 +228,16 @@ class UnpackOperation:
["unsquashfs", "-l", entry.source]
)
if entry.sourcefs == "ext4":
elif entry.sourcefs == "ext4":
fslist = subprocess.check_output(
["find", imgmountdir, "-type", "f"]
)
elif entry.is_file():
# Hasn't been mounted, copy directly; find handles both
# files and directories.
fslist = subprocess.check_output(["find", entry.source, "-type", "f"])
entry.total = len(fslist.splitlines())
self.report_progress()
@ -247,9 +255,15 @@ class UnpackOperation:
"""
Mount given image as loop device.
A *file* entry (e.g. one with *sourcefs* set to *file*)
is not mounted and just ignored.
:param entry:
:param imgmountdir:
"""
if entry.is_file():
return
if os.path.isdir(entry.source):
subprocess.check_call(["mount",
"--bind", entry.source,
@ -287,12 +301,18 @@ class UnpackOperation:
self.report_progress()
try:
return file_copy(imgmountdir, entry.destination, progress_cb)
if entry.is_file():
source = entry.source
else:
source = imgmountdir
return file_copy(source, entry.destination, progress_cb)
finally:
subprocess.check_call(["umount", "-l", imgmountdir])
if not entry.is_file():
subprocess.check_call(["umount", "-l", imgmountdir])
def get_supported_filesystems():
def get_supported_filesystems_kernel():
"""
Reads /proc/filesystems (the list of supported filesystems
for the current kernel) and returns a list of (names of)
@ -310,6 +330,14 @@ def get_supported_filesystems():
return []
def get_supported_filesystems():
"""
Returns a list of all the supported filesystems
(valid values for the *sourcefs* key in an item.
"""
return ["file"] + get_supported_filesystems_kernel()
def run():
"""
Unsquash filesystem.
@ -330,8 +358,7 @@ def run():
supported_filesystems = get_supported_filesystems()
unpack = list()
# Bail out before we start when there are obvious problems
for entry in job.configuration["unpack"]:
source = os.path.abspath(entry["source"])
sourcefs = entry["sourcefs"]
@ -340,14 +367,18 @@ def run():
utils.warning("The filesystem for \"{}\" ({}) is not supported".format(source, sourcefs))
return (_("Bad unsquash configuration"),
_("The filesystem for \"{}\" ({}) is not supported").format(source, sourcefs))
destination = os.path.abspath(root_mount_point + entry["destination"])
if not os.path.exists(source):
utils.warning("The source filesystem \"{}\" does not exist".format(source))
return (_("Bad unsquash configuration"),
_("The source filesystem \"{}\" does not exist").format(source))
unpack = list()
for entry in job.configuration["unpack"]:
source = os.path.abspath(entry["source"])
sourcefs = entry["sourcefs"]
destination = os.path.abspath(root_mount_point + entry["destination"])
if not os.path.isdir(destination):
utils.warning(("The destination \"{}\" in the target system is not a directory").format(destination))
return (_("Bad unsquash configuration"),

View File

@ -9,30 +9,59 @@
# target dir relative to rootMountPoint.
---
unpack:
# Each list item is unpacked, in order, to the target system.
#
# Each list item has the following attributes:
# source: path relative to the live / intstalling system to the image
# sourcefs: ext4 or squashfs (may be others if mount supports it)
# sourcefs: the type of the source files; valid entries are
# - *ext4* (copies the filesystem contents)
# - *squashfs* (unsquashes)
# - *file* (copies a file or directory)
# - (may be others if mount supports it)
# destination: path relative to rootMountPoint (so in the target
# system) where this filesystem is unpacked.
# system) where this filesystem is unpacked. It may be an
# empty string, which effectively is / (the root) of the target
# system.
#
# EXAMPLES
#
# Usually you list a filesystem image to unpack; you can use
# squashfs or an ext4 image.
#
# - source: "/path/to/filesystem.sqfs"
# sourcefs: "squashfs"
# destination: ""
# You can list more than one filesystem.
#
# Multiple entries are unpacked in-order
#
# - source: "/path/to/another/filesystem.img"
# sourcefs: "ext4"
# destination: ""
# - source: "/path/to/another/filesystem2.img"
# sourcefs: "ext4"
# destination: "/usr/lib/extra"
#
# You can list filesystem source paths relative to the Calamares run
# directory, if you use -d (this is only useful for testing, though).
- source: ./example.sqfs
sourcefs: squashfs
destination: ""
#
# - source: ./example.sqfs
# sourcefs: squashfs
# destination: ""
#
# You can list individual files (copied one-by-one), or directories
# (the files inside this directory are copied directly to the destination,
# so no "dummycpp/" subdirectory is created in this example).
# Do note that the target directory must exist already (e.g. from
# extracting some other filesystem).
#
# - source: ../CHANGES
# sourcefs: file
# destination: "/tmp/derp"
# - source: ../src/modules/dummycpp
# sourcefs: file
# destination: "/tmp/derp"
unpack:
- source: ../CHANGES
sourcefs: file
destination: "/tmp"