diff --git a/recipe.json b/recipe.json index 782b1d0b..155f30dc 100644 --- a/recipe.json +++ b/recipe.json @@ -13,7 +13,8 @@ "/boot": 900, "/boot/efi": 512, "/": 21504, - "/var": 25600 + "/var": 25600, + "/var/home": 5120 }, "tour": { "welcome": { diff --git a/vanilla_installer/defaults/disk.py b/vanilla_installer/defaults/disk.py index 8b4ed2fc..f0230207 100644 --- a/vanilla_installer/defaults/disk.py +++ b/vanilla_installer/defaults/disk.py @@ -149,6 +149,7 @@ class PartitionSelector(Adw.PreferencesPage): bios_part = Gtk.Template.Child() root_part = Gtk.Template.Child() var_part = Gtk.Template.Child() + home_part = Gtk.Template.Child() swap_part = Gtk.Template.Child() boot_part_expand = Gtk.Template.Child() @@ -156,6 +157,7 @@ class PartitionSelector(Adw.PreferencesPage): bios_part_expand = Gtk.Template.Child() root_part_expand = Gtk.Template.Child() var_part_expand = Gtk.Template.Child() + home_part_expand = Gtk.Template.Child() swap_part_expand = Gtk.Template.Child() use_swap_part = Gtk.Template.Child() @@ -166,6 +168,7 @@ class PartitionSelector(Adw.PreferencesPage): bios_small_error = Gtk.Template.Child() root_small_error = Gtk.Template.Child() var_small_error = Gtk.Template.Child() + home_small_error = Gtk.Template.Child() # NOTE: Keys must be the same name as template children __selected_partitions: dict[str, dict[str, Union[Partition, str, None]]] = { @@ -199,6 +202,12 @@ class PartitionSelector(Adw.PreferencesPage): "partition": None, "fstype": None, }, + "home_part_expand": { + "mountpoint": "/var/home", + "min_size": 5_368_709_120, # 5 GB + "partition": None, + "fstype": None, + }, "swap_part_expand": { "mountpoint": "swap", "partition": None, @@ -280,6 +289,16 @@ def __init__(self, parent, partitions, **kwargs): ) self.__selected_partitions["var_part_expand"]["fstype"] = "btrfs" + self.__home_part_rows = self.__generate_partition_list_widgets( + self.home_part_expand, "ext4" + ) + for i, widget in enumerate(self.__home_part_rows): + self.home_part_expand.add_row(widget) + widget.add_siblings( + self.__home_part_rows[:i] + self.__home_part_rows[i + 1 :] + ) + self.__selected_partitions["home_part_expand"]["fstype"] = "ext4" + self.__swap_part_rows = self.__generate_partition_list_widgets( self.swap_part_expand, "swap", False ) @@ -290,7 +309,7 @@ def __init__(self, parent, partitions, **kwargs): ) self.__selected_partitions["swap_part_expand"]["fstype"] = "swap" - for widget in [self.boot_part, self.efi_part, self.root_part, self.var_part]: + for widget in [self.boot_part, self.efi_part, self.root_part, self.var_part, self.home_part]: widget.set_description(widget.get_description() + self.get_partition_size_string(widget) + ".") self.update_apply_button_status() @@ -360,6 +379,8 @@ def check_selected_partitions_sizes(self): self.root_part_expand.get_style_context().remove_class("error") if self.var_part_expand.get_style_context().has_class("error"): self.var_part_expand.get_style_context().remove_class("error") + if self.home_part_expand.get_style_context().has_class("error"): + self.home_part_expand.get_style_context().remove_class("error") for partition, info in self.__selected_partitions.items(): if "min_size" in info and info["partition"] is not None: @@ -384,6 +405,10 @@ def check_selected_partitions_sizes(self): self.var_part_expand.get_style_context().add_class("error") self.var_small_error.set_description(error_description) self.var_small_error.set_visible(True) + elif partition == "home_part_expand": + self.home_part_expand.get_style_context().add_class("error") + self.home_small_error.set_description(error_description) + self.home_small_error.set_visible(True) # Special case for BIOS, where the partitions needs to be EXACTLY 1 MiB if not Systeminfo.is_uefi(): @@ -408,6 +433,8 @@ def get_partition_size_string(self, widget): size = self.__recipe["min_partition_sizes"]["/"] if widget == self.var_part: size = self.__recipe["min_partition_sizes"]["/var"] + if widget == self.home_part: + size = self.__recipe["min_partition_sizes"]["/var/home"] if size > 1024: return str(int(size/1024)) + "GiB" else: @@ -439,6 +466,7 @@ def update_partition_rows(self): self.__boot_part_rows, self.__root_part_rows, self.__var_part_rows, + self.__home_part_rows, self.__swap_part_rows, ] diff --git a/vanilla_installer/gtk/widget-partition.ui b/vanilla_installer/gtk/widget-partition.ui index a49ddf75..7f79d65b 100644 --- a/vanilla_installer/gtk/widget-partition.ui +++ b/vanilla_installer/gtk/widget-partition.ui @@ -137,6 +137,39 @@ false + + + Home Partition + A custom home partition allows you to store your files in a seperate partition from your system so that you can keep your files when changing Linux distributions. The minimum size for this partition is + + + Home Partition + Choose a partition to use as a home partition + + + 3 + + + use_home_part + + + + + + No Partition Selected + Please select a partition from the options below + + + + + + + + false + + Swap Partition diff --git a/vanilla_installer/utils/processor.py b/vanilla_installer/utils/processor.py index 4488264c..34c30b10 100644 --- a/vanilla_installer/utils/processor.py +++ b/vanilla_installer/utils/processor.py @@ -293,6 +293,7 @@ def __gen_auto_partition_steps( mountpoints.append(["/dev/vos-root/root-a", "/"]) mountpoints.append(["/dev/vos-root/root-b", "/"]) mountpoints.append(["/dev/vos-var/var", "/var"]) + mountpoints.append(["/dev/vos-home/home", "/var/home"]) return setup_steps, mountpoints, post_install_steps, disk @@ -405,6 +406,8 @@ def setup_partition( setup_steps.append([part_disk, "setflag", [part_number, "esp", True]]) elif values["mp"] == "/var": setup_partition("vos-var", encrypt, password) + elif values["mp"] == "/var/home": + setup_partition("vos-home", encrypt, password) elif values["mp"] == "swap": post_install_steps.append(["swapon", [part], True]) @@ -417,6 +420,7 @@ def __find_partitions(recipe: AlbiusRecipe) -> tuple[str, str, str, str, str]: root_a_partition = "" root_b_partition = "" var_partition = "" + home_partition = "" for mnt in recipe.mountpoints: if mnt["target"] == "/boot": @@ -430,6 +434,8 @@ def __find_partitions(recipe: AlbiusRecipe) -> tuple[str, str, str, str, str]: root_b_partition = mnt["partition"] elif mnt["target"] == "/var": var_partition = mnt["partition"] + elif mnt["target"] == "/var/home": + home_partition = mnt["partition"] return ( boot_partition, @@ -437,6 +443,7 @@ def __find_partitions(recipe: AlbiusRecipe) -> tuple[str, str, str, str, str]: root_a_partition, root_b_partition, var_partition, + home_partition, ) @staticmethod @@ -502,17 +509,21 @@ def gen_install_recipe(log_path, finals, sys_recipe): root_a_part, root_b_part, var_part, + home_part ) = Processor.__find_partitions(recipe) if "VANILLA_SKIP_POSTINSTALL" not in os.environ: # Adapt root A filesystem structure if encrypt: var_label = f"/dev/mapper/luks-$(lsblk -d -y -n -o UUID {var_part})" + home_label = f"/dev/mapper/luks-$(lsblk -d -y -n -o UUID {home_part})" else: var_label = var_part + home_label = home_part recipe.add_postinstall_step( "shell", [ + "unmount /mnt/a/var/home", "umount /mnt/a/var", "mkdir /mnt/a/tmp-boot", "cp -r /mnt/a/boot /mnt/a/tmp-boot", @@ -529,10 +540,30 @@ def gen_install_recipe(log_path, finals, sys_recipe): for path in _REL_SYSTEM_LINKS ], f"mount {var_label} /mnt/a/var", + f"mount {home_label} /mnt/a/var/home" if home_label != "" else "", f"mount {boot_part} /mnt/a/boot{f' && mount {efi_part} /mnt/a/boot/efi' if efi_part else ''}", ], ) + # Setup the home partition in /etc/fstab + if home_label != "": + i = 0 + while i < len(finals): + if "disk" in finals[i]: + break + i += 1 + home_type = finals[i]["disk"][home_part]["fs"] + i = 0 + + recipe.add_postinstall_step( + "shell", + [ + "touch /etc/fstab", + f"echo \"{home_part} /var/home {home_type} defaults 0 2\" >> /etc/fstab", + ], + chroot=True + ) + # Create default user # This needs to be done after mounting `/etc` overlay, so set it as # late post-install @@ -657,7 +688,6 @@ def gen_install_recipe(log_path, finals, sys_recipe): "mkdir -p /var/lib/abroot/etc/vos-a /var/lib/abroot/etc/vos-b /var/lib/abroot/etc/vos-a-work /var/lib/abroot/etc/vos-b-work", "mount -t overlay overlay -o lowerdir=/.system/etc,upperdir=/var/lib/abroot/etc/vos-a,workdir=/var/lib/abroot/etc/vos-a-work /etc", "mv /var/storage /var/lib/abroot/", - "mount -o bind /var/home /home", "mount -o bind /var/opt /opt", ], chroot=True,