Loading pkgs/by-name/ca/calamares-nixos-extensions/src/config/modules/mount.conf +14 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,20 @@ extraMounts: mountPoint: /sys/firmware/efi/efivars efi: true # Ensure the right fmask/dmask is set on the ESP, as it will be # picked up by nixos-generate-config later # Btrfs subvolume layout for NixOS # Empty subvolume for / means no subvolume (top-level) for GRUB compatibility btrfsSubvolumes: - mountPoint: / subvolume: "" - mountPoint: /home subvolume: /home - mountPoint: /nix subvolume: /nix # Mount options by filesystem type # nixos-generate-config picks these up for hardware-configuration.nix mountOptions: - filesystem: efi options: [ fmask=0077, dmask=0077 ] - filesystem: btrfs options: [ compress=zstd, noatime ] pkgs/by-name/ca/calamares-nixos-extensions/src/config/modules/partition.conf +19 −1 Original line number Diff line number Diff line Loading @@ -12,11 +12,29 @@ userSwapChoices: luksGeneration: luks2 defaultFileSystemType: "ext4" availableFileSystemTypes: - ext4 - btrfs - xfs - f2fs showNotEncryptedBootMessage: false bios: mountPoint: "/boot" minimumSize: 512MiB recommendedSize: 1GiB label: "BOOT" partitionLayout: - name: "root" - name: "boot" filesystem: "ext4" mountPoint: "/boot" size: 1GiB - name: "root" filesystem: "unknown" noEncrypt: false mountPoint: "/" size: 100% pkgs/by-name/ca/calamares-nixos-extensions/src/modules/nixos/main.py +87 −5 Original line number Diff line number Diff line Loading @@ -45,6 +45,15 @@ cfgbootbios = """ # Bootloader. """ cfgbootbiosbtrfs = """ # Bootloader. boot.loader.grub.enable = true; boot.loader.grub.device = "@@bootdev@@"; boot.loader.grub.useOSProber = true; # Use provided UUIDs instead of blkid probing (required for btrfs subvolumes) boot.loader.grub.fsIdentifier = "provided"; """ cfgbootnone = """ # Disable bootloader. boot.loader.grub.enable = false; Loading Loading @@ -360,6 +369,46 @@ def catenate(d, key, *values): d[key] = "".join(values) def fix_btrfs_subvolumes(hardware_config, partitions): """ Fix btrfs subvolume configuration in hardware-configuration.nix. nixos-generate-config generates incorrect subvol options for btrfs by setting them to mount points instead of actual subvolume names. This function corrects the subvol options to match what Calamares configured. """ # Map of mount points to their correct btrfs subvolume names # These match what is configured in mount.conf btrfsSubvolumes # Root uses top-level (no subvolume) for GRUB compatibility subvol_map = { "/home": "home", "/nix": "nix", } # Check if root is actually btrfs root_is_btrfs = False for part in partitions: if part.get("mountPoint") == "/" and part.get("fs") == "btrfs": root_is_btrfs = True break if not root_is_btrfs: return hardware_config libcalamares.utils.debug("Fixing btrfs subvolume configuration") # Fix subvol options for each mount point # nixos-generate-config may generate "subvol=/" instead of "subvol=@" for mount_point, correct_subvol in subvol_map.items(): # Match any "subvol=<something>" and replace with correct subvolume # This handles cases like "subvol=/" or "subvol=/home" pattern = r'(fileSystems\."{}"[^;]*"subvol=)[^"]*"'.format(re.escape(mount_point)) replacement = r'\g<1>{}"'.format(correct_subvol) hardware_config = re.sub(pattern, replacement, hardware_config, flags=re.DOTALL) return hardware_config def run(): """NixOS Configuration.""" Loading Loading @@ -388,10 +437,21 @@ def run(): # Pick config parts and prepare substitution # Check if root filesystem is btrfs root_is_btrfs = False for part in gs.value("partitions"): if part.get("mountPoint") == "/" and part.get("fs") == "btrfs": root_is_btrfs = True break # Check bootloader if fw_type == "efi": cfg += cfgbootefi elif bootdev != "nodev": # Use btrfs-specific config to avoid blkid issues with subvolumes if root_is_btrfs: cfg += cfgbootbiosbtrfs else: cfg += cfgbootbios catenate(variables, "bootdev", bootdev) else: Loading Loading @@ -734,9 +794,20 @@ def run(): libcalamares.utils.error(e.output.decode("utf8")) return (_("nixos-generate-config failed"), _(e.output.decode("utf8"))) # Check for unfree stuff in hardware-configuration.nix # Read and fix hardware-configuration.nix hf = open(root_mount_point + "/etc/nixos/hardware-configuration.nix", "r") htxt = hf.read() hf.close() hardware_modified = False # Fix btrfs subvolume configuration if needed htxt_fixed = fix_btrfs_subvolumes(htxt, gs.value("partitions")) if htxt_fixed != htxt: htxt = htxt_fixed hardware_modified = True # Check for unfree stuff in hardware-configuration.nix search = re.search(r"boot\.extraModulePackages = \[ (.*) \];", htxt) # Check if any extraModulePackages are defined, and remove if only free packages are allowed Loading Loading @@ -765,14 +836,17 @@ def run(): ) ) expkgs.remove(pkg) hardwareout = re.sub( htxt = re.sub( r"boot\.extraModulePackages = \[ (.*) \];", "boot.extraModulePackages = [ {}];".format( "".join(map(lambda x: x + " ", expkgs)) ), htxt, ) # Write the hardware-configuration.nix file hardware_modified = True # Write the hardware-configuration.nix file if modified if hardware_modified: libcalamares.utils.host_env_process_output( [ "cp", Loading @@ -780,7 +854,7 @@ def run(): root_mount_point + "/etc/nixos/hardware-configuration.nix", ], None, hardwareout, htxt, ) # Write the configuration.nix file Loading @@ -789,6 +863,14 @@ def run(): status = _("Installing NixOS") libcalamares.job.setprogress(0.3) try: subprocess.check_output( ["pkexec", "chmod", "755", root_mount_point], stderr=subprocess.STDOUT, ) except subprocess.CalledProcessError as e: libcalamares.utils.warning("Failed to set permissions on {}: {}".format(root_mount_point, e.output)) # build nixos-install command nixosInstallCmd = [ "pkexec" ] nixosInstallCmd.extend(generateProxyStrings()) Loading Loading
pkgs/by-name/ca/calamares-nixos-extensions/src/config/modules/mount.conf +14 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,20 @@ extraMounts: mountPoint: /sys/firmware/efi/efivars efi: true # Ensure the right fmask/dmask is set on the ESP, as it will be # picked up by nixos-generate-config later # Btrfs subvolume layout for NixOS # Empty subvolume for / means no subvolume (top-level) for GRUB compatibility btrfsSubvolumes: - mountPoint: / subvolume: "" - mountPoint: /home subvolume: /home - mountPoint: /nix subvolume: /nix # Mount options by filesystem type # nixos-generate-config picks these up for hardware-configuration.nix mountOptions: - filesystem: efi options: [ fmask=0077, dmask=0077 ] - filesystem: btrfs options: [ compress=zstd, noatime ]
pkgs/by-name/ca/calamares-nixos-extensions/src/config/modules/partition.conf +19 −1 Original line number Diff line number Diff line Loading @@ -12,11 +12,29 @@ userSwapChoices: luksGeneration: luks2 defaultFileSystemType: "ext4" availableFileSystemTypes: - ext4 - btrfs - xfs - f2fs showNotEncryptedBootMessage: false bios: mountPoint: "/boot" minimumSize: 512MiB recommendedSize: 1GiB label: "BOOT" partitionLayout: - name: "root" - name: "boot" filesystem: "ext4" mountPoint: "/boot" size: 1GiB - name: "root" filesystem: "unknown" noEncrypt: false mountPoint: "/" size: 100%
pkgs/by-name/ca/calamares-nixos-extensions/src/modules/nixos/main.py +87 −5 Original line number Diff line number Diff line Loading @@ -45,6 +45,15 @@ cfgbootbios = """ # Bootloader. """ cfgbootbiosbtrfs = """ # Bootloader. boot.loader.grub.enable = true; boot.loader.grub.device = "@@bootdev@@"; boot.loader.grub.useOSProber = true; # Use provided UUIDs instead of blkid probing (required for btrfs subvolumes) boot.loader.grub.fsIdentifier = "provided"; """ cfgbootnone = """ # Disable bootloader. boot.loader.grub.enable = false; Loading Loading @@ -360,6 +369,46 @@ def catenate(d, key, *values): d[key] = "".join(values) def fix_btrfs_subvolumes(hardware_config, partitions): """ Fix btrfs subvolume configuration in hardware-configuration.nix. nixos-generate-config generates incorrect subvol options for btrfs by setting them to mount points instead of actual subvolume names. This function corrects the subvol options to match what Calamares configured. """ # Map of mount points to their correct btrfs subvolume names # These match what is configured in mount.conf btrfsSubvolumes # Root uses top-level (no subvolume) for GRUB compatibility subvol_map = { "/home": "home", "/nix": "nix", } # Check if root is actually btrfs root_is_btrfs = False for part in partitions: if part.get("mountPoint") == "/" and part.get("fs") == "btrfs": root_is_btrfs = True break if not root_is_btrfs: return hardware_config libcalamares.utils.debug("Fixing btrfs subvolume configuration") # Fix subvol options for each mount point # nixos-generate-config may generate "subvol=/" instead of "subvol=@" for mount_point, correct_subvol in subvol_map.items(): # Match any "subvol=<something>" and replace with correct subvolume # This handles cases like "subvol=/" or "subvol=/home" pattern = r'(fileSystems\."{}"[^;]*"subvol=)[^"]*"'.format(re.escape(mount_point)) replacement = r'\g<1>{}"'.format(correct_subvol) hardware_config = re.sub(pattern, replacement, hardware_config, flags=re.DOTALL) return hardware_config def run(): """NixOS Configuration.""" Loading Loading @@ -388,10 +437,21 @@ def run(): # Pick config parts and prepare substitution # Check if root filesystem is btrfs root_is_btrfs = False for part in gs.value("partitions"): if part.get("mountPoint") == "/" and part.get("fs") == "btrfs": root_is_btrfs = True break # Check bootloader if fw_type == "efi": cfg += cfgbootefi elif bootdev != "nodev": # Use btrfs-specific config to avoid blkid issues with subvolumes if root_is_btrfs: cfg += cfgbootbiosbtrfs else: cfg += cfgbootbios catenate(variables, "bootdev", bootdev) else: Loading Loading @@ -734,9 +794,20 @@ def run(): libcalamares.utils.error(e.output.decode("utf8")) return (_("nixos-generate-config failed"), _(e.output.decode("utf8"))) # Check for unfree stuff in hardware-configuration.nix # Read and fix hardware-configuration.nix hf = open(root_mount_point + "/etc/nixos/hardware-configuration.nix", "r") htxt = hf.read() hf.close() hardware_modified = False # Fix btrfs subvolume configuration if needed htxt_fixed = fix_btrfs_subvolumes(htxt, gs.value("partitions")) if htxt_fixed != htxt: htxt = htxt_fixed hardware_modified = True # Check for unfree stuff in hardware-configuration.nix search = re.search(r"boot\.extraModulePackages = \[ (.*) \];", htxt) # Check if any extraModulePackages are defined, and remove if only free packages are allowed Loading Loading @@ -765,14 +836,17 @@ def run(): ) ) expkgs.remove(pkg) hardwareout = re.sub( htxt = re.sub( r"boot\.extraModulePackages = \[ (.*) \];", "boot.extraModulePackages = [ {}];".format( "".join(map(lambda x: x + " ", expkgs)) ), htxt, ) # Write the hardware-configuration.nix file hardware_modified = True # Write the hardware-configuration.nix file if modified if hardware_modified: libcalamares.utils.host_env_process_output( [ "cp", Loading @@ -780,7 +854,7 @@ def run(): root_mount_point + "/etc/nixos/hardware-configuration.nix", ], None, hardwareout, htxt, ) # Write the configuration.nix file Loading @@ -789,6 +863,14 @@ def run(): status = _("Installing NixOS") libcalamares.job.setprogress(0.3) try: subprocess.check_output( ["pkexec", "chmod", "755", root_mount_point], stderr=subprocess.STDOUT, ) except subprocess.CalledProcessError as e: libcalamares.utils.warning("Failed to set permissions on {}: {}".format(root_mount_point, e.output)) # build nixos-install command nixosInstallCmd = [ "pkexec" ] nixosInstallCmd.extend(generateProxyStrings()) Loading