]> glassweightruler.freedombox.rocks Git - waydroid.git/commitdiff
Mount overlays on top of image mount points
authorSebastian Krzyszkowiak <dos@dosowisko.net>
Thu, 10 Nov 2022 21:00:34 +0000 (22:00 +0100)
committerAlessandro Astone <ales.astone@gmail.com>
Thu, 12 Jan 2023 20:31:19 +0000 (21:31 +0100)
This allows the user to make modifications to the images that may persist
between image upgrades.

For both the system and vendor image there's a set of two overlays.
One, specified in config as "overlay", is a read-only persistent overlay
meant for stuff like installing privileged apps that should persist.
Second one, specified as "overlay-rw", is a read-write overlay that
stores the changes made by the user in case they remount the mount point
in read-write mode. This one is meant to be removed when performing
image upgrade to not carry on potentially incompatible changes between
images.

tools/actions/initializer.py
tools/config/__init__.py
tools/helpers/images.py
tools/helpers/mount.py

index 7fec7325f2cb905daf411e0672fa7184c20c258d..31b4fc90253ca720b6a0440b3e1b426540e049a0 100644 (file)
@@ -119,6 +119,13 @@ def init(args):
             helpers.images.get(args)
         if not os.path.isdir(tools.config.defaults["rootfs"]):
             os.mkdir(tools.config.defaults["rootfs"])
+        if not os.path.isdir(tools.config.defaults["overlay"]):
+            os.mkdir(tools.config.defaults["overlay"])
+            os.mkdir(tools.config.defaults["overlay"]+"/vendor")
+        if not os.path.isdir(tools.config.defaults["overlay_rw"]):
+            os.mkdir(tools.config.defaults["overlay_rw"])
+            os.mkdir(tools.config.defaults["overlay_rw"]+"/system")
+            os.mkdir(tools.config.defaults["overlay_rw"]+"/vendor")
         helpers.lxc.setup_host_perms(args)
         helpers.lxc.set_lxc_config(args)
         helpers.lxc.make_base_props(args)
index 0ed3d46ffa00af9a119c1f89a43f6ef28c67b579..1edbf1761ade67fb3e09158ae7b0b563f0b102ac 100644 (file)
@@ -40,6 +40,9 @@ defaults = {
 }
 defaults["images_path"] = defaults["work"] + "/images"
 defaults["rootfs"] = defaults["work"] + "/rootfs"
+defaults["overlay"] = defaults["work"] + "/overlay"
+defaults["overlay_rw"] = defaults["work"] + "/overlay_rw"
+defaults["overlay_work"] = defaults["work"] + "/overlay_work"
 defaults["data"] = defaults["work"] + "/data"
 defaults["lxc"] = defaults["work"] + "/lxc"
 defaults["host_perms"] = defaults["work"] + "/host-permissions"
index cf65a119f40ef4b40274d0a5bae35bceb0e49428..e00e9b1f43359f955d5cabae0184a064c3de964e 100644 (file)
@@ -128,8 +128,19 @@ def make_prop(args, cfg, full_props_path):
 def mount_rootfs(args, images_dir, session):
     helpers.mount.mount(args, images_dir + "/system.img",
                         tools.config.defaults["rootfs"], umount=True)
+    helpers.mount.mount_overlay(args, [tools.config.defaults["overlay"],
+                                       tools.config.defaults["rootfs"]],
+                                tools.config.defaults["rootfs"],
+                                upper_dir=tools.config.defaults["overlay_rw"] + "/system",
+                                work_dir=tools.config.defaults["overlay_work"] + "/system")
     helpers.mount.mount(args, images_dir + "/vendor.img",
                            tools.config.defaults["rootfs"] + "/vendor")
+    helpers.mount.mount_overlay(args, [tools.config.defaults["overlay"] + "/vendor",
+                                       tools.config.defaults["rootfs"] + "/vendor"],
+                                tools.config.defaults["rootfs"] + "/vendor",
+                                upper_dir=tools.config.defaults["overlay_rw"] + "/vendor",
+                                work_dir=tools.config.defaults["overlay_work"] + "/vendor")
+
     for egl_path in ["/vendor/lib/egl", "/vendor/lib64/egl"]:
         if os.path.isdir(egl_path):
             helpers.mount.bind(
index 2660952696a156b2b0e266be58feb6098c12baf5..a0d34be5d8a8d6e1f0614ac88ae45bd7a39762d8 100644 (file)
@@ -149,3 +149,28 @@ def mount(args, source, destination, create_folders=True, umount=False,
     # Verify, that it has worked
     if not ismount(destination):
         raise RuntimeError("Mount failed: " + source + " -> " + destination)
+
+def mount_overlay(args, lower_dirs, destination, upper_dir=None, work_dir=None,
+                  create_folders=True, readonly=True):
+    """
+    Mount an overlay.
+    """
+    dirs = [*lower_dirs]
+    options = ["xino=off", "lowerdir=" + (":".join(lower_dirs))]
+
+    if upper_dir:
+        dirs.append(upper_dir)
+        dirs.append(work_dir)
+        options.append("upperdir=" + upper_dir)
+        options.append("workdir=" + work_dir)
+
+    for dir_path in dirs:
+        if not os.path.exists(dir_path):
+            if create_folders:
+                tools.helpers.run.user(args, ["mkdir", "-p", dir_path])
+            else:
+                raise RuntimeError("Mount failed, folder does not exist: " +
+                                   dir_path)
+
+    mount(args, "overlay", destination, mount_type="overlay", options=options,
+          readonly=readonly, create_folders=create_folders, force=True)