def free_space_on_disks(self): for disk in self.scheme.disks(): # ask for clearing the whole disk if 'y' == ask_user( f"Delete all partitions on disk '{disk.url}'? [y/N]:" ).lower(): disk.create_new_partition_table() # otherwise ask for removing individual partitions else: t = SpawnedSU(f"parted {disk.url} print") partitions = [ line.strip() for line in t.datalines if line.strip() and line.strip()[0].isdigit() ] for partition in partitions: print(f"Partition [[ {log.ok_blue_s(partition)} ]]") partition_id = re.search(r"(\d+)", partition).group() if 'y' == ask_user( f"Delete partition {disk.url}{partition_id} [y/N]:" ).lower(): SpawnedSU.do( f"sgdisk --delete={partition_id} {disk.url}") print(f" * Partition {disk.url}{partition_id} DELETED", end="\n\n")
def unmount_target_system(self): mounts = SpawnedSU.do(f'mount | grep "{self.chroot}" | cut -d" " -f3', list_=True) mounts.reverse() for m in mounts: SpawnedSU.do(f"umount {m}") self.scheme.execute(Release())
def mount_target_system(self): SpawnedSU.do(f"mkdir -p {self.chroot}") self.scheme.execute(Involve(chroot=self.chroot)) SpawnedSU.do(f""" for n in sys proc dev etc/resolv.conf sys/firmware/efi/efivars; do mount --bind /$n {self.chroot}/$n; done mount -t devpts devpts {self.chroot}/dev/pts """)
def _setup_unattended_installation(self): if not Path("/etc/calamares").exists(): return packagename = util.package_name() calamares_modules = [ str(f.locate()) for f in app_files(packagename) if "calamares" in str(f) and str(f).endswith(".conf") ] if calamares_modules: SpawnedSU.do(f"mkdir -p /etc/calamares/modules && cp {' '.join(calamares_modules)} /etc/calamares/modules")
def deploy_resource(filename, dst_path, owner=None, mode=None): src_path = resource_file(filename) dst_full_path = dst_path if dst_path.endswith( filename) else f"{dst_path}/{filename}" if not Path(dst_full_path).parent.exists(): colored_warn = logger.fail_s("WARNING:") _tlog( f"{colored_warn} Path {Path(dst_full_path).parent} doesn't exist; deploy_resource('{filename}') skipped" ) return # just skip processing for now owner = owner or owner_uid(Path(dst_full_path).parent) mode = mode or 0o664 SpawnedSU.do(f""" cp {src_path} {dst_path} chown {owner}:{owner} {dst_full_path} chmod {mode} {dst_full_path} """)
def _begin_installation(self): if 0: # calamares Spawned.do("/usr/bin/calamares_polkit", timeout=Spawned.TIMEOUT_INFINITE) else: # manjaro-architect # ensure the setup script is installed if not SpawnedSU.do("which setup || pacman -S manjaro-architect --noconfirm --needed --noprogressbar", with_status=True).success: _tlog("manjaro-architect isn't available. Abort...") app_exit() # run manjaro-architect t = SpawnedSU("setup", timeout=Spawned.TIMEOUT_INFINITE) t.interact_user() t.waitfor(SpawnedSU.TASK_END)
def _prepare_installation(self): # clear partman cache SpawnedSU.do("rm -rf /var/lib/partman") # clear debconf cache # note: removing the DB leads the ubiquity installer to crash SpawnedSU.do_script(""" if [ ! -d /var/cache/debconf.back ]; then cp -r /var/cache/debconf/ /var/cache/debconf.back else rm -rf /var/cache/debconf cp -r /var/cache/debconf.back /var/cache/debconf fi """) # ensure crypt/lvm volumes are available dm_list = Spawned.do(f"ls /dev/mapper", list_=True) for pt in [pt for pt in self.scheme if pt.mapperID]: if isinstance(pt.parent, Disk) and pt.mapperID not in dm_list: pt.execute(Involve()) # wait for Partman and modify values in background PartmanHelper(self.scheme).run()
def _format(partition): if "efi" in partition.mountpoint: cmd = f"mkfs.vfat {_options(partition)} %s" elif partition.mountpoint == "/boot": cmd = f"mkfs.ext2 {_options(partition)} %s" elif partition.mountpoint == "swap": cmd = f"mkswap {_options(partition)} %s" elif partition.fs: cmd = f"mkfs.{partition.fs} {_options(partition)} %s" else: cmd = f"mkfs.ext4 {_options(partition)} %s" SpawnedSU.do(cmd % partition.url) if partition.fs == "btrfs" and partition.subvolumes: root = "/mnt" SpawnedSU.do(f"mount -o compress=lzo {partition.url} {root}") for subv, mpoint in partition.subvolumes.items(): SpawnedSU.do( f"mkdir -p {root}{mpoint} && btrfs subvolume create {root}/{subv}" ) SpawnedSU.do(f"umount {partition.url}")
def _mount(partition, chroot, mountpoint=None, mount_options=''): if partition.isswap: SpawnedSU.do(f"swapon {partition.url}") else: assert chroot, f"No 'chroot' defined while trying to mount '{partition.id}'" mpoint = mountpoint or partition.mountpoint if not mpoint: # prevent incorrect mounting to chroot's '/' return # note: if Path() gets several absolute paths, the last one is taken as an anchor # so we need to strip the leading '/' from the second path # TODO: find a better way to concatenate 2 absolute paths if mpoint.startswith('/'): mpoint = mpoint.lstrip('/') mpoint = Path(chroot, mpoint) SpawnedSU.do(f"mkdir -p {mpoint}") SpawnedSU.do(f"mount {mount_options} {partition.url} {mpoint}")
def select_target_disk(): SpawnedSU.do(r"parted -ls 2>/dev/null | egrep --color 'Disk\s+/dev|[kMG\d]B\s|Size'") return ask_user("Select target disk:")
def test_luks_key(volume_url, key): return SpawnedSU.do( f"cryptsetup open --test-passphrase -d {key} {volume_url} 2>/dev/null", with_status=True).success
def _setup_unattended_installation(self): if seed_file := util.target.preseeding_file(): SpawnedSU.do(f"debconf-set-selections {seed_file}")
def _umount(partition): if partition.isswap: SpawnedSU.do(f"swapoff {partition.url}") else: SpawnedSU.do(f"umount {partition.url}")
def _luks_close(partition, mapper_id=None): name_to_close = partition.mapperID or mapper_id assert name_to_close, f"Is it LUKS? 'mapperID' is not defined for {partition.id}" SpawnedSU.do(f"cryptsetup close {name_to_close}")
def on_exit(): if DisksMountHelper.daemon_active and not DisksMountHelper.is_daemon_active( ): SpawnedSU.do("systemctl start udisks2.service") print("udisks2.service started")
def __init__(self): DisksMountHelper.daemon_active = self.is_daemon_active() if DisksMountHelper.daemon_active: SpawnedSU.do("systemctl stop udisks2.service") print("udisks2.service stopped")
def create_new_partition_table(self): SpawnedSU.do(f"sgdisk --zap-all {self.url}")
def discardable(partition): pattern = "TRIM supported" return solid(partition.url) and \ pattern in SpawnedSU.do(f'sudo hdparm -I {partition.disk} | grep "{pattern}"')
def serve_lvm_on_luks_vg(self, pt): SpawnedSU.do(f"sudo vgchange -ay {pt.lvm_vg}")
def uuid(volume_url): return SpawnedSU.do(f"blkid -s UUID -o value {volume_url}")