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") if os.path.exists(plymouth_bin): use_splash = "splash" else: use_splash = "" if "swap" in self.mount_devices: cmd_linux_default = 'resume=UUID={0} quiet {1}'.format( self.swap_uuid, use_splash) else: cmd_linux_default = 'quiet {0}'.format(use_splash) self.set_grub_option("GRUB_THEME", "/boot/grub/themes/Antergos-Default/theme.txt") self.set_grub_option("GRUB_CMDLINE_LINUX_DEFAULT", cmd_linux_default) self.set_grub_option("GRUB_DISTRIBUTOR", "Antergos") if self.settings.get('use_luks'): # Should fix issue #352 # GRUB_ENABLE_CRYPTODISK=1 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) root_device = self.root_device if self.method == "advanced" and self.settings.get( 'use_luks_in_root'): # Special case, in advanced when using luks in root device, we store it in luks_root_device root_device = self.settings.get('luks_root_device') root_uuid = fs.get_uuid(root_device) logging.debug("Root device: %s", root_device) cmd_linux = "cryptdevice=/dev/disk/by-uuid/{0}:{1}".format( root_uuid, 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.boot_uuid) # Store grub line in settings, we'll use it later in check_root_uuid_in_grub() self.settings.set('GRUB_CMDLINE_LINUX', cmd_linux) # Store grub line in /etc/default/grub file self.set_grub_option("GRUB_CMDLINE_LINUX", cmd_linux) logging.debug("Grub configuration completed successfully.")
def __init__(self, dest_dir, settings, mount_devices): self.dest_dir = dest_dir self.settings = settings self.mount_devices = mount_devices self.method = settings.get("partition_mode") self.root_device = self.mount_devices["/"] self.root_uuid = fs.get_uuid(self.root_device) if "swap" in self.mount_devices: swap_partition = self.mount_devices["swap"] self.swap_uuid = fs.get_uuid(swap_partition) if "/boot" in self.mount_devices: boot_device = self.mount_devices["/boot"] else: # No dedicated /boot partition boot_device = self.mount_devices["/"] self.boot_uuid = fs.get_uuid(boot_device)
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") if os.path.exists(plymouth_bin): use_splash = "splash" else: use_splash = "" if "swap" in self.mount_devices: cmd_linux_default = 'resume=UUID={0} quiet {1}'.format(self.swap_uuid, use_splash) else: cmd_linux_default = 'quiet {0}'.format(use_splash) self.set_grub_option("GRUB_THEME", "/boot/grub/themes/Antergos-Default/theme.txt") self.set_grub_option("GRUB_CMDLINE_LINUX_DEFAULT", cmd_linux_default) self.set_grub_option("GRUB_DISTRIBUTOR", "Antergos") if self.settings.get('use_luks'): # Should fix issue #352 # GRUB_ENABLE_CRYPTODISK=1 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) root_device = self.root_device if self.method == "advanced" and self.settings.get('use_luks_in_root'): # Special case, in advanced when using luks in root device, we store it in luks_root_device root_device = self.settings.get('luks_root_device') root_uuid = fs.get_uuid(root_device) logging.debug("Root device: %s", root_device) cmd_linux = "cryptdevice=/dev/disk/by-uuid/{0}:{1}".format(root_uuid, 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.boot_uuid) # Store grub line in settings, we'll use it later in check_root_uuid_in_grub() self.settings.set('GRUB_CMDLINE_LINUX', cmd_linux) # Store grub line in /etc/default/grub file self.set_grub_option("GRUB_CMDLINE_LINUX", cmd_linux) logging.debug("Grub configuration completed successfully.")
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 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["/"] = root_device key = "" if not self.settings.get("luks_root_password"): key = "cryptkey=UUID={0}:ext2:/.keyfile-root" key = key.format(self.uuids["/boot"]) options = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" options = options.format( self.uuids["/"], luks_root_volume, key, luks_root_volume_uuid)
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\n") menu_file.write("timeout 3\n") # 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\tReborn OS\n") conf['default'].append("linux\t/vmlinuz-linux\n") conf['default'].append("initrd\t/intel-ucode.img\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\tReborn (fallback)\n") conf['fallback'].append("linux\t/vmlinuz-linux\n") conf['fallback'].append("initrd\t/intel-ucode.img\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\tReborn LTS\n") conf['lts'].append("linux\t/vmlinuz-linux-lts\n") conf['lts'].append("initrd\t/intel-ucode.img\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\tReborn LTS (fallback)\n") conf['lts_fallback'].append("linux\t/vmlinuz-linux-lts\n") conf['lts_fallback'].append("initrd\t/intel-ucode.img\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 auto_fstab(self): """ Create /etc/fstab file """ all_lines = ["# /etc/fstab: static file system information.", "#", "# Use 'blkid' to print the universally unique identifier for a", "# device; this may be used with UUID= as a more robust way to name devices", "# that works even if disks are added and removed. See fstab(5).", "#", "# <file system> <mount point> <type> <options> <dump> <pass>", "#"] use_luks = self.settings.get("use_luks") use_lvm = self.settings.get("use_lvm") # Use lsblk to be able to match LUKS UUID with mapper UUID pknames = fs.get_pknames() for mount_point in self.mount_devices: partition_path = self.mount_devices[mount_point] uuid = fs.get_uuid(partition_path) if uuid == "": logging.warning( _("Can't get {0} partition UUID. It won't be added to fstab"), partition_path) continue if partition_path in self.fs_devices: myfmt = self.fs_devices[partition_path] else: # It hasn't any filesystem defined, skip it. continue # Take care of swap partitions if "swap" in myfmt: # If using a TRIM supported SSD, discard is a valid mount option for swap if partition_path in self.ssd: opts = "defaults,discard" else: opts = "defaults" txt = "UUID={0} swap swap {1} 0 0".format(uuid, opts) all_lines.append(txt) logging.debug("Added %s to fstab", txt) continue crypttab_path = os.path.join(DEST_DIR, 'etc/crypttab') # Fix for home + luks, no lvm (from Automatic Install) if "/home" in mount_point and self.method == "automatic" and use_luks and not use_lvm: # Modify the crypttab file luks_root_password = self.settings.get("luks_root_password") if luks_root_password and len(luks_root_password) > 0: # Use password and not a keyfile home_keyfile = "none" else: # Use a keyfile home_keyfile = "/etc/luks-keys/home" os.chmod(crypttab_path, 0o666) with open(crypttab_path, 'a') as crypttab_file: line = "cryptAntergosHome /dev/disk/by-uuid/{0} {1} luks\n".format(uuid, home_keyfile) crypttab_file.write(line) logging.debug("Added %s to crypttab", line) os.chmod(crypttab_path, 0o600) # Add line to fstab txt = "/dev/mapper/cryptAntergosHome {0} {1} defaults 0 0".format(mount_point, myfmt) all_lines.append(txt) logging.debug("Added %s to fstab", txt) continue # Add all LUKS partitions from Advanced Install (except root). if self.method == "advanced" and mount_point is not "/" and use_luks and "/dev/mapper" in partition_path: # As the mapper with the filesystem will have a different UUID than # the partition it is encrypted in, we have to take care of this here. # Then we will be able to add it to crypttab vol_name = partition_path[len("/dev/mapper/"):] try: luks_partition_path = "/dev/" + pknames[vol_name] except KeyError: logging.error("Can't find the PKNAME value of %s", partition_path) continue luks_uuid = fs.get_uuid(luks_partition_path) if len(luks_uuid) > 0: # OK, add it to crypttab with the correct uuid os.chmod(crypttab_path, 0o666) with open(crypttab_path, 'a') as crypttab_file: line = "{0} /dev/disk/by-uuid/{1} none luks\n".format(vol_name, luks_uuid) crypttab_file.write(line) logging.debug("Added %s to crypttab", line) os.chmod(crypttab_path, 0o600) else: logging.error("Can't add luks uuid to crypttab for %s partition", luks_partition_path) continue # Finally, the fstab line to mount the unencrypted file system # if a mount point has been specified by the user if len(mount_point) > 0: txt = "{0} {1} {2} defaults 0 0".format(partition_path, mount_point, myfmt) all_lines.append(txt) logging.debug("Added %s to fstab", txt) continue # fstab uses vfat to mount fat16 and fat32 partitions if "fat" in myfmt: myfmt = 'vfat' if "btrfs" in myfmt: self.settings.set('btrfs', True) # Avoid adding a partition to fstab when it has no mount point (swap has been checked above) if mount_point == "": continue # Create mount point on destination system if it yet doesn't exist full_path = os.path.join(DEST_DIR, mount_point) os.makedirs(full_path, mode=0o755, exist_ok=True) # Is ssd ? # Device list example: {'/dev/sdb': False, '/dev/sda': True} logging.debug("Device list : {0}".format(self.ssd)) device = re.sub("[0-9]+$", "", partition_path) is_ssd = self.ssd.get(device) logging.debug("Device: {0}, SSD: {1}".format(device, is_ssd)) # Add mount options parameters if not is_ssd: if "btrfs" in myfmt: opts = 'defaults,rw,relatime,space_cache,autodefrag,inode_cache' elif "f2fs" in myfmt: opts = 'defaults,rw,noatime' elif "ext3" in myfmt or "ext4" in myfmt: opts = 'defaults,rw,relatime,data=ordered' else: opts = 'defaults,rw,relatime' else: # As of linux kernel version 3.7, the following # filesystems support TRIM: ext4, btrfs, JFS, and XFS. if myfmt == 'ext4' or myfmt == 'jfs' or myfmt == 'xfs': opts = 'defaults,rw,noatime,discard' elif myfmt == 'btrfs': opts = 'defaults,rw,noatime,compress=lzo,ssd,discard,space_cache,autodefrag,inode_cache' else: opts = 'defaults,rw,noatime' no_check = ["btrfs", "f2fs"] if mount_point == "/" and myfmt not in no_check: chk = '1' else: chk = '0' if mount_point == "/": self.settings.set('ruuid', uuid) txt = "UUID={0} {1} {2} {3} 0 {4}".format(uuid, mount_point, myfmt, opts, chk) all_lines.append(txt) logging.debug("Added %s to fstab", txt) full_text = '\n'.join(all_lines) + '\n' fstab_path = os.path.join(DEST_DIR, 'etc/fstab') with open(fstab_path, 'w') as fstab_file: fstab_file.write(full_text) logging.debug("fstab written.")
def install_systemd_boot(self): """ Install Systemd-boot (Gummiboot) bootloader to the EFI System Partition """ # 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 = {} if not self.settings.get('use_luks'): 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\troot=UUID={0} rw quiet\n\n".format(self.root_uuid)) 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\troot=UUID={0} rw quiet\n\n".format(self.root_uuid)) 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\troot=UUID={0} rw quiet\n\n".format( self.root_uuid)) conf['lts_fallback'] = [] conf['lts_fallback'].append( "title\tAntergos LTS (fallback)\n\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\troot=UUID={0} rw quiet\n\n".format( self.root_uuid)) else: luks_root_volume = self.settings.get('luks_root_volume') luks_root_volume_uuid = fs.get_uuid( "/dev/mapper/{0}".format(luks_root_volume)) # In automatic mode, root_device is in self.mount_devices, as it should be root_device = self.root_device if self.method == "advanced" and self.settings.get( 'use_luks_in_root'): root_device = self.settings.get('luks_root_device') root_uuid = fs.get_uuid(root_device) key = "" if self.settings.get("luks_root_password") == "": key = "cryptkey=UUID={0}:ext2:/.keyfile-root".format( self.boot_uuid) root_uuid_line = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" root_uuid_line = root_uuid_line.format(root_uuid, luks_root_volume, key, luks_root_volume_uuid) conf['default'] = [] conf['default'].append("title\tAntergos\n") conf['default'].append("linux\t/vmlinuz-linux\n") conf['default'].append( "options\tinitrd=/initramfs-linux.img {0}\n\n".format( root_uuid_line)) conf['fallback'] = [] conf['fallback'].append("title\tAntergos (fallback)\n") conf['fallback'].append("linux\t/vmlinuz-linux\n") conf['fallback'].append( "options\tinitrd=/initramfs-linux-fallback.img {0}\n\n".format( root_uuid_line)) 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( "options\tinitrd=/initramfs-linux-lts.img {0}\n\n".format( root_uuid_line)) 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( "options\tinitrd=/initramfs-linux-lts-fallback.img {0}\n\n" .format(root_uuid_line)) # 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...") try: # chroot.mount_special_dirs(self.dest_dir) cmd = ['bootctl', '--path=/boot', 'install'] chroot.run(cmd, self.dest_dir, 300) # chroot.umount_special_dirs(self.dest_dir) logging.info("Systemd-boot install completed successfully") self.settings.set('bootloader_installation_successful', True) except subprocess.CalledProcessError as process_error: logging.error('Command %s failed. Error output: %s', " ".join(cmd), process_error.output) self.settings.set('bootloader_installation_successful', False) except subprocess.TimeoutExpired: logging.error('Command %s timed out.', " ".join(cmd)) self.settings.set('bootloader_installation_successful', False) except Exception as general_error: logging.error('Command %s failed. Unknown Error: %s', " ".join(cmd), general_error) self.settings.set('bootloader_installation_successful', False)
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": try: swap_devices = check_output("swapon -s") if device in swap_devices: subprocess.check_call(["swapoff", device]) subprocess.check_call(["mkswap", "-L", label_name, device]) subprocess.check_call(["swapon", device]) except subprocess.CalledProcessError as err: txt = "Can't activate swap in {0}. Command {1} has failed: {2}".format( device, err.cmd, err.output) logging.warning(txt) 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] try: subprocess.check_call(command.split()) except subprocess.CalledProcessError as err: txt = "Can't create filesystem {0}. Command {1} failed: {2}".format( fs_type, err.cmd, err.output) logging.error(txt) txt = _("Can't create filesystem {0}. Command {1} failed: {2}" ).format(fs_type, err.cmd, err.output) raise InstallError(txt) # Flush filesystem buffers try: subprocess.check_call(["sync"]) except subprocess.CalledProcessError as err: txt = "Command {0} failed: {1}".format(err.cmd, err.output) logging.warning(txt) # 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,inode_cache' try: cmd = ["mount", "-t", fs_type, "-o", mopts, device, path] subprocess.check_call(cmd) except subprocess.CalledProcessError as err: txt = "Error trying to mount {0} in {1}. Command {2} failed: {3}".format( device, path, err.cmd, err.output) logging.error(txt) txt = _( "Error trying to mount {0} in {1}. Command {2} failed: {3}" ).format(device, path, err.cmd, err.output) raise InstallError(txt) # 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) logging.debug("Device details: %s UUID=%s LABEL=%s", device, fs_uuid, fs_label)
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 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["/"] = root_device key = "" if not self.settings.get("luks_root_password"): key = "cryptkey=UUID={0}:ext2:/.keyfile-root" key = key.format(self.uuids["/boot"]) options = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" options = options.format( self.uuids["/"], luks_root_volume, key, luks_root_volume_uuid) 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") 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") 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 install_systemd_boot(self): """ Install Systemd-boot (Gummiboot) bootloader to the EFI System Partition """ # 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 = {} if not self.settings.get('use_luks'): 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\troot=UUID={0} rw quiet\n\n".format(self.root_uuid)) 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\troot=UUID={0} rw quiet\n\n".format(self.root_uuid)) 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\troot=UUID={0} rw quiet\n\n".format(self.root_uuid)) conf['lts_fallback'] = [] conf['lts_fallback'].append("title\tAntergos LTS (fallback)\n\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\troot=UUID={0} rw quiet\n\n".format(self.root_uuid)) else: luks_root_volume = self.settings.get('luks_root_volume') luks_root_volume_uuid = fs.get_uuid("/dev/mapper/{0}".format(luks_root_volume)) # In automatic mode, root_device is in self.mount_devices, as it should be root_device = self.root_device if self.method == "advanced" and self.settings.get('use_luks_in_root'): root_device = self.settings.get('luks_root_device') root_uuid = fs.get_uuid(root_device) key = "" if self.settings.get("luks_root_password") == "": key = "cryptkey=UUID={0}:ext2:/.keyfile-root".format(self.boot_uuid) root_uuid_line = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" root_uuid_line = root_uuid_line.format(root_uuid, luks_root_volume, key, luks_root_volume_uuid) conf['default'] = [] conf['default'].append("title\tAntergos\n") conf['default'].append("linux\t/vmlinuz-linux\n") conf['default'].append("options\tinitrd=/initramfs-linux.img {0}\n\n".format(root_uuid_line)) conf['fallback'] = [] conf['fallback'].append("title\tAntergos (fallback)\n") conf['fallback'].append("linux\t/vmlinuz-linux\n") conf['fallback'].append("options\tinitrd=/initramfs-linux-fallback.img {0}\n\n".format(root_uuid_line)) 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("options\tinitrd=/initramfs-linux-lts.img {0}\n\n".format(root_uuid_line)) 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("options\tinitrd=/initramfs-linux-lts-fallback.img {0}\n\n".format(root_uuid_line)) # 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...") try: # chroot.mount_special_dirs(self.dest_dir) cmd = ['bootctl', '--path=/boot', 'install'] chroot.run(cmd, self.dest_dir, 300) # chroot.umount_special_dirs(self.dest_dir) logging.info("Systemd-boot install completed successfully") self.settings.set('bootloader_installation_successful', True) except subprocess.CalledProcessError as process_error: logging.error('Command %s failed. Error output: %s', " ".join(cmd), process_error.output) self.settings.set('bootloader_installation_successful', False) except subprocess.TimeoutExpired: logging.error('Command %s timed out.', " ".join(cmd)) self.settings.set('bootloader_installation_successful', False) except Exception as general_error: logging.error('Command %s failed. Unknown Error: %s', " ".join(cmd), general_error) self.settings.set('bootloader_installation_successful', False)
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/Vimix/theme.txt") self.set_grub_option("GRUB_DISTRIBUTOR", "Reborn") 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 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 = '' if os.path.exists(plymouth_bin): use_splash = "splash" else: use_splash = "" if self.settings.get("zfs"): pool = self.settings.get("zfs_pool_name") cmd_linux_default = 'root=ZFS={0} boot=zfs rpool={0} bootfs={0}/boot '.format(pool) if "swap" in self.uuids: cmd_linux_default += 'resume=UUID={0} quiet {1}'.format( self.uuids["swap"], use_splash) else: cmd_linux_default += 'quiet {0}'.format(use_splash) self.set_grub_option( "GRUB_THEME", "/boot/grub/themes/Antergos-Default/theme.txt") self.set_grub_option("GRUB_CMDLINE_LINUX_DEFAULT", cmd_linux_default) self.set_grub_option("GRUB_DISTRIBUTOR", "Antergos") 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}" cmd_linux = cmd_linux.format(self.uuids["/"], luks_root_volume) if self.settings.get("luks_root_password") == "": # No luks password, so user wants to use a keyfile cryptkey = " cryptkey=/dev/disk/by-uuid/{0}:ext2:/.keyfile-root" cryptkey = cryptkey.format(self.uuids["/boot"]) cmd_linux += cryptkey # Store grub line in settings, we'll use it later in # check_root_uuid_in_grub() self.settings.set('GRUB_CMDLINE_LINUX', cmd_linux) # Store grub line in /etc/default/grub file self.set_grub_option("GRUB_CMDLINE_LINUX", cmd_linux) 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": try: swap_devices = check_output("swapon -s") if device in swap_devices: subprocess.check_call(["swapoff", device]) subprocess.check_call(["mkswap", "-L", label_name, device]) subprocess.check_call(["swapon", device]) except subprocess.CalledProcessError as err: txt = "Can't activate swap in {0}. Command {1} has failed: {2}".format(device, err.cmd, err.output) logging.warning(txt) 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] try: subprocess.check_call(command.split()) except subprocess.CalledProcessError as err: txt = "Can't create filesystem {0}. Command {1} failed: {2}".format(fs_type, err.cmd, err.output) logging.error(txt) txt = _("Can't create filesystem {0}. Command {1} failed: {2}").format(fs_type, err.cmd, err.output) raise InstallError(txt) # Flush filesystem buffers try: subprocess.check_call(["sync"]) except subprocess.CalledProcessError as err: txt = "Command {0} failed: {1}".format(err.cmd, err.output) logging.warning(txt) # 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,inode_cache' try: cmd = ["mount", "-t", fs_type, "-o", mopts, device, path] subprocess.check_call(cmd) except subprocess.CalledProcessError as err: txt = "Error trying to mount {0} in {1}. Command {2} failed: {3}".format(device, path, err.cmd, err.output) logging.error(txt) txt = _("Error trying to mount {0} in {1}. Command {2} failed: {3}").format(device, path, err.cmd, err.output) raise InstallError(txt) # 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) logging.debug("Device details: %s UUID=%s LABEL=%s", device, fs_uuid, fs_label)