def __init__(self, dest_dir, settings, mount_devices): self.dest_dir = dest_dir self.settings = settings self.mount_devices = mount_devices self.uuids = {} if "/" in self.mount_devices: self.uuids["/"] = fs.get_uuid(self.mount_devices["/"]) else: logging.error( "Cannot install bootloader, root device has not been specified!" ) if "swap" in self.mount_devices: self.uuids["swap"] = fs.get_uuid(self.mount_devices["swap"]) if "/boot" in self.mount_devices: self.uuids["/boot"] = fs.get_uuid(self.mount_devices["/boot"]) elif "/" in self.mount_devices: # No dedicated /boot partition self.uuids["/boot"] = self.uuids["/"] else: logging.error( "Cannot install bootloader, root device has not been specified!" )
def modify_grub_default(self): """ If using LUKS as root, we need to modify GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX : Command-line arguments to add to menu entries for the Linux kernel. GRUB_CMDLINE_LINUX_DEFAULT : Unless ‘GRUB_DISABLE_RECOVERY’ is set to ‘true’, two menu entries will be generated for each Linux kernel: one default entry and one entry for recovery mode. This option lists command-line arguments to add only to the default menu entry, after those listed in ‘GRUB_CMDLINE_LINUX’. """ plymouth_bin = os.path.join(self.dest_dir, "usr/bin/plymouth") cmd_linux_default = "quiet" cmd_linux = "" # https://www.kernel.org/doc/Documentation/kernel-parameters.txt # cmd_linux_default : quiet splash resume=UUID=ABC zfs=ABC if os.path.exists(plymouth_bin): cmd_linux_default += " splash" # resume does not work in zfs (or so it seems) if "swap" in self.uuids and not self.settings.get("zfs"): cmd_linux_default += " resume=UUID={0}".format(self.uuids["swap"]) if self.settings.get("zfs"): zfs_pool_name = self.settings.get("zfs_pool_name") cmd_linux += " zfs={0}".format(zfs_pool_name) if self.settings.get('use_luks'): # When using separate boot partition, # add GRUB_ENABLE_CRYPTODISK to grub.cfg if self.uuids["/"] != self.uuids["/boot"]: self.set_grub_option("GRUB_ENABLE_CRYPTODISK", "y") # Let GRUB automatically add the kernel parameters for # root encryption luks_root_volume = self.settings.get('luks_root_volume') logging.debug("Luks Root Volume: %s", luks_root_volume) if (self.settings.get("partition_mode") == "advanced" and self.settings.get('use_luks_in_root')): # In advanced, if using luks in root device, # we store root device it in luks_root_device var root_device = self.settings.get('luks_root_device') self.uuids["/"] = fs.get_uuid(root_device) cmd_linux += " cryptdevice=/dev/disk/by-uuid/{0}:{1}".format( self.uuids["/"], luks_root_volume) if self.settings.get("luks_root_password") == "": # No luks password, so user wants to use a keyfile cmd_linux += " cryptkey=/dev/disk/by-uuid/{0}:ext2:/.keyfile-root".format( self.uuids["/boot"]) # Remove leading/ending spaces cmd_linux_default = cmd_linux_default.strip() cmd_linux = cmd_linux.strip() # Modify /etc/default/grub self.set_grub_option("GRUB_THEME", "/boot/grub/themes/Antergos-Default/theme.txt") self.set_grub_option("GRUB_DISTRIBUTOR", "Antergos") self.set_grub_option("GRUB_CMDLINE_LINUX_DEFAULT", cmd_linux_default) self.set_grub_option("GRUB_CMDLINE_LINUX", cmd_linux) # Also store grub line in settings, we'll use it later in check_root_uuid_in_grub() try: self.settings.set('GRUB_CMDLINE_LINUX', cmd_linux) except AttributeError: pass logging.debug("Grub configuration completed successfully.")
def mkfs(self, device, fs_type, mount_point, label_name, fs_options="", btrfs_devices=""): """ We have two main cases: "swap" and everything else. """ logging.debug("Will format device %s as %s", device, fs_type) if fs_type == "swap": err_msg = "Can't activate swap in {0}".format(device) swap_devices = call(["swapon", "-s"], msg=err_msg) if device in swap_devices: call(["swapoff", device], msg=err_msg) cmd = ["mkswap", "-L", label_name, device] call(cmd, msg=err_msg) cmd = ["swapon", device] call(cmd, msg=err_msg) else: mkfs = { "xfs": "mkfs.xfs {0} -L {1} -f {2}".format(fs_options, label_name, device), "jfs": "yes | mkfs.jfs {0} -L {1} {2}".format(fs_options, label_name, device), "reiserfs": "yes | mkreiserfs {0} -l {1} {2}".format(fs_options, label_name, device), "ext2": "mkfs.ext2 -q {0} -F -L {1} {2}".format(fs_options, label_name, device), "ext3": "mkfs.ext3 -q {0} -F -L {1} {2}".format(fs_options, label_name, device), "ext4": "mkfs.ext4 -q {0} -F -L {1} {2}".format(fs_options, label_name, device), "btrfs": "mkfs.btrfs {0} -L {1} {2}".format(fs_options, label_name, btrfs_devices), "nilfs2": "mkfs.nilfs2 {0} -L {1} {2}".format(fs_options, label_name, device), "ntfs-3g": "mkfs.ntfs {0} -L {1} {2}".format(fs_options, label_name, device), "vfat": "mkfs.vfat {0} -n {1} {2}".format(fs_options, label_name, device), "f2fs": "mkfs.f2fs {0} -l {1} {2}".format(fs_options, label_name, device), } # Make sure the fs type is one we can handle if fs_type not in mkfs.keys(): txt = _("Unknown filesystem type {0}").format(fs_type) raise InstallError(txt) command = mkfs[fs_type] err_msg = "Can't create filesystem {0}".format(fs_type) call(command.split(), msg=err_msg, fatal=True) # Flush filesystem buffers call(["sync"]) # Create our mount directory path = self.dest_dir + mount_point os.makedirs(path, mode=0o755, exist_ok=True) # Mount our new filesystem mopts = "rw,relatime" if fs_type == "ext4": mopts = "rw,relatime,data=ordered" elif fs_type == "btrfs": mopts = "rw,relatime,space_cache,autodefrag" err_msg = "Error trying to mount {0} in {1}".format(device, path) cmd = ["mount", "-t", fs_type, "-o", mopts, device, path] call(cmd, msg=err_msg, fatal=True) # Change permission of base directories to avoid btrfs issues if mount_point == "/tmp": mode = 0o1777 elif mount_point == "/root": mode = 0o750 else: mode = 0o755 os.chmod(path, mode) fs_uuid = fs.get_uuid(device) fs_label = fs.get_label(device) msg = "Device details: %s UUID=%s LABEL=%s" logging.debug(msg, device, fs_uuid, fs_label)
def mkfs(self, device, fs_type, mount_point, label_name, fs_options="", btrfs_devices=""): """ We have two main cases: "swap" and everything else. """ logging.debug("Will format device %s as %s", device, fs_type) if fs_type == "swap": err_msg = "Can't activate swap in {0}".format(device) swap_devices = call(["swapon","-s"], msg=err_msg) if device in swap_devices: call(["swapoff", device], msg=err_msg) cmd = ["mkswap", "-L", label_name, device] call(cmd, msg=err_msg) cmd = ["swapon", device] call(cmd, msg=err_msg) else: mkfs = {"xfs": "mkfs.xfs {0} -L {1} -f {2}".format(fs_options, label_name, device), "jfs": "yes | mkfs.jfs {0} -L {1} {2}".format(fs_options, label_name, device), "reiserfs": "yes | mkreiserfs {0} -l {1} {2}".format(fs_options, label_name, device), "ext2": "mkfs.ext2 -q {0} -F -L {1} {2}".format(fs_options, label_name, device), "ext3": "mkfs.ext3 -q {0} -F -L {1} {2}".format(fs_options, label_name, device), "ext4": "mkfs.ext4 -q {0} -F -L {1} {2}".format(fs_options, label_name, device), "btrfs": "mkfs.btrfs {0} -L {1} {2}".format(fs_options, label_name, btrfs_devices), "nilfs2": "mkfs.nilfs2 {0} -L {1} {2}".format(fs_options, label_name, device), "ntfs-3g": "mkfs.ntfs {0} -L {1} {2}".format(fs_options, label_name, device), "vfat": "mkfs.vfat {0} -n {1} {2}".format(fs_options, label_name, device), "f2fs": "mkfs.f2fs {0} -l {1} {2}".format(fs_options, label_name, device)} # Make sure the fs type is one we can handle if fs_type not in mkfs.keys(): txt = _("Unknown filesystem type {0}").format(fs_type) raise InstallError(txt) command = mkfs[fs_type] err_msg = "Can't create filesystem {0}".format(fs_type) call(command.split(), msg=err_msg, fatal=True) # Flush filesystem buffers call(["sync"]) # Create our mount directory path = self.dest_dir + mount_point os.makedirs(path, mode=0o755, exist_ok=True) # Mount our new filesystem mopts = "rw,relatime" if fs_type == "ext4": mopts = "rw,relatime,data=ordered" elif fs_type == "btrfs": mopts = 'rw,relatime,space_cache,autodefrag' err_msg = "Error trying to mount {0} in {1}".format(device, path) cmd = ["mount", "-t", fs_type, "-o", mopts, device, path] call(cmd, msg=err_msg, fatal=True) # Change permission of base directories to avoid btrfs issues if mount_point == "/tmp": mode = 0o1777 elif mount_point == "/root": mode = 0o750 else: mode = 0o755 os.chmod(path, mode) fs_uuid = fs.get_uuid(device) fs_label = fs.get_label(device) msg = "Device details: %s UUID=%s LABEL=%s" logging.debug(msg, device, fs_uuid, fs_label)
def install(self): """ Install Systemd-boot bootloader to the EFI System Partition """ logging.debug("Cnchi will install the Systemd-boot (Gummiboot) loader") # Setup bootloader menu menu_dir = os.path.join(self.dest_dir, "boot/loader") os.makedirs(menu_dir, mode=0o755, exist_ok=True) menu_path = os.path.join(menu_dir, "loader.conf") with open(menu_path, 'w') as menu_file: menu_file.write("default antergos") # Setup boot entries conf = {} options = "" if not self.settings.get('use_luks'): options = "root=UUID={0} rw quiet".format(self.uuids["/"]) else: luks_root_volume = self.settings.get('luks_root_volume') logging.debug("Luks Root Volume: %s", luks_root_volume) mapper = "/dev/mapper/{0}".format(luks_root_volume) luks_root_volume_uuid = fs.get_uuid(mapper) if (self.settings.get("partition_mode") == "advanced" and self.settings.get('use_luks_in_root')): # In advanced, if using luks in root device, # we store root device it in luks_root_device var root_device = self.settings.get('luks_root_device') self.uuids["/"] = fs.get_uuid(root_device) key = "" if not self.settings.get("luks_root_password"): key = "cryptkey=UUID={0}:ext2:/.keyfile-root" key = key.format(self.uuids["/boot"]) if not self.settings.get('use_lvm'): options = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" options = options.format( self.uuids["/"], luks_root_volume, key, luks_root_volume_uuid) else: # Quick fix for issue #595 (lvm+luks) options = "cryptdevice=UUID={0}:{1} {2} root=/dev/dm-1 rw quiet" options = options.format( self.uuids["/"], luks_root_volume, key) if self.settings.get("zfs"): zfs_pool_name = self.settings.get("zfs_pool_name") options += ' zfs={0}'.format(zfs_pool_name) conf['default'] = [] conf['default'].append("title\tAntergos\n") conf['default'].append("linux\t/vmlinuz-linux\n") conf['default'].append("initrd\t/initramfs-linux.img\n") conf['default'].append("options\t{0}\n\n".format(options)) conf['fallback'] = [] conf['fallback'].append("title\tAntergos (fallback)\n") conf['fallback'].append("linux\t/vmlinuz-linux\n") conf['fallback'].append("initrd\t/initramfs-linux-fallback.img\n") conf['fallback'].append("options\t{0}\n\n".format(options)) if self.settings.get('feature_lts'): conf['lts'] = [] conf['lts'].append("title\tAntergos LTS\n") conf['lts'].append("linux\t/vmlinuz-linux-lts\n") conf['lts'].append("initrd\t/initramfs-linux-lts.img\n") conf['lts'].append("options\t{0}\n\n".format(options)) conf['lts_fallback'] = [] conf['lts_fallback'].append("title\tAntergos LTS (fallback)\n") conf['lts_fallback'].append("linux\t/vmlinuz-linux-lts\n") conf['lts_fallback'].append("initrd\t/initramfs-linux-lts-fallback.img\n") conf['lts_fallback'].append("options\t{0}\n\n".format(options)) # Write boot entries entries_dir = os.path.join(self.dest_dir, "boot/loader/entries") os.makedirs(entries_dir, mode=0o755, exist_ok=True) entry_path = os.path.join(entries_dir, "antergos.conf") with open(entry_path, 'w') as entry_file: for line in conf['default']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['fallback']: entry_file.write(line) if self.settings.get('feature_lts'): entry_path = os.path.join(entries_dir, "antergos-lts.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-lts-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts_fallback']: entry_file.write(line) # Install bootloader logging.debug("Installing systemd-boot bootloader...") cmd = ['bootctl', '--path=/boot', 'install'] if chroot_call(cmd, self.dest_dir, 300) is False: self.settings.set('bootloader_installation_successful', False) else: self.settings.set('bootloader_installation_successful', True)
def modify_grub_default(self): """ If using LUKS as root, we need to modify GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX : Command-line arguments to add to menu entries for the Linux kernel. GRUB_CMDLINE_LINUX_DEFAULT : Unless ‘GRUB_DISABLE_RECOVERY’ is set to ‘true’, two menu entries will be generated for each Linux kernel: one default entry and one entry for recovery mode. This option lists command-line arguments to add only to the default menu entry, after those listed in ‘GRUB_CMDLINE_LINUX’. """ plymouth_bin = os.path.join(self.dest_dir, "usr/bin/plymouth") cmd_linux_default = "quiet" cmd_linux = "" # https://www.kernel.org/doc/Documentation/kernel-parameters.txt # cmd_linux_default : quiet splash resume=UUID=ABC zfs=ABC if os.path.exists(plymouth_bin): cmd_linux_default += " splash" # resume does not work in zfs (or so it seems) if "swap" in self.uuids and not self.settings.get("zfs"): cmd_linux_default += " resume=UUID={0}".format(self.uuids["swap"]) if self.settings.get("zfs"): zfs_pool_name = self.settings.get("zfs_pool_name") cmd_linux += " zfs={0}".format(zfs_pool_name) if self.settings.get("use_luks"): # When using separate boot partition, # add GRUB_ENABLE_CRYPTODISK to grub.cfg if self.uuids["/"] != self.uuids["/boot"]: self.set_grub_option("GRUB_ENABLE_CRYPTODISK", "y") # Let GRUB automatically add the kernel parameters for # root encryption luks_root_volume = self.settings.get("luks_root_volume") logging.debug("Luks Root Volume: %s", luks_root_volume) if self.settings.get("partition_mode") == "advanced" and self.settings.get("use_luks_in_root"): # In advanced, if using luks in root device, # we store root device it in luks_root_device var root_device = self.settings.get("luks_root_device") self.uuids["/"] = fs.get_uuid(root_device) cmd_linux += " cryptdevice=/dev/disk/by-uuid/{0}:{1}".format(self.uuids["/"], luks_root_volume) if self.settings.get("luks_root_password") == "": # No luks password, so user wants to use a keyfile cmd_linux += " cryptkey=/dev/disk/by-uuid/{0}:ext2:/.keyfile-root".format(self.uuids["/boot"]) # Remove leading/ending spaces cmd_linux_default = cmd_linux_default.strip() cmd_linux = cmd_linux.strip() # Modify /etc/default/grub self.set_grub_option("GRUB_THEME", "/boot/grub/themes/Antergos-Default/theme.txt") self.set_grub_option("GRUB_DISTRIBUTOR", "Antergos") self.set_grub_option("GRUB_CMDLINE_LINUX_DEFAULT", cmd_linux_default) self.set_grub_option("GRUB_CMDLINE_LINUX", cmd_linux) # Also store grub line in settings, we'll use it later in check_root_uuid_in_grub() try: self.settings.set("GRUB_CMDLINE_LINUX", cmd_linux) except AttributeError: pass logging.debug("Grub configuration completed successfully.")