nixos/scripts/format-disk.py

152 lines
4.3 KiB
Python
Raw Normal View History

2021-12-19 18:41:03 +01:00
#!/usr/bin/env python3
2021-12-20 10:41:11 +01:00
import getpass
2021-12-19 18:58:31 +01:00
import os
2021-12-19 18:41:03 +01:00
import subprocess
2021-12-19 19:15:01 +01:00
import sys
2021-12-19 18:41:03 +01:00
2021-12-23 11:22:42 +01:00
def _run_command(command, user_input=""):
if user_input:
2021-12-20 10:41:11 +01:00
result = subprocess.run(command,
capture_output=True,
text=True,
check=True,
2021-12-23 11:22:42 +01:00
input=user_input)
2021-12-20 10:41:11 +01:00
else:
result = subprocess.run(command,
capture_output=True,
text=True,
check=True)
2021-12-19 18:41:03 +01:00
return result
2021-12-19 18:58:31 +01:00
def _get_system_memory():
mem_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')
mem_gib = mem_bytes / (1024.**3)
return round(mem_gib)
2021-12-19 19:14:23 +01:00
def _y_n(question):
answer = input("{} (Y/N): ".format(question))
if answer.lower() == "y":
return True
if answer.lower() == "n":
return False
2021-12-23 11:22:42 +01:00
print("Please only answer with Y or N!")
2021-12-19 19:14:23 +01:00
sys.exit(1)
2021-12-19 18:47:36 +01:00
def read_disks():
2021-12-19 18:41:03 +01:00
output = _run_command(["lsblk", "-dpno", "name"])
disks = []
for disk in output.stdout.splitlines():
if "loop" in disk:
continue
disks.append(disk)
return disks
2021-12-19 18:47:36 +01:00
def create_menu(disks):
2021-12-23 11:22:42 +01:00
for position, disk in enumerate(disks):
print("{}: {}".format(position, disk))
2021-12-19 18:41:03 +01:00
2021-12-19 18:47:36 +01:00
def get_disk_to_format():
2021-12-19 18:41:03 +01:00
disk_to_format = input("Which disk dou you want to format?: ")
return int(disk_to_format)
2021-12-19 18:41:03 +01:00
2021-12-20 12:24:33 +01:00
def create_partition_table(disk):
2021-12-20 15:32:11 +01:00
print("Create partition table.")
2021-12-20 15:42:58 +01:00
_run_command(["parted", "--script", disk, "mklabel", "gpt"])
def _partition_suffix(disk):
if "nvmne" in disk:
return "p"
return ""
2021-12-19 20:10:49 +01:00
def create_boot_partition(disk):
boot_partition = "{}{}1".format(disk, _partition_suffix(disk))
print("Create boot partition {}.".format(boot_partition))
2021-12-20 15:44:51 +01:00
_run_command(["parted", "--script", disk, "mkpart",
2021-12-23 11:22:42 +01:00
"ESP", "fat32", "1MiB", "512MiB"])
2021-12-20 15:55:27 +01:00
_run_command(["parted", "--script", disk, "set", "1", "esp", "on"])
_run_command(["mkfs.fat", "-F", "32", "-n", "BOOT", boot_partition])
2021-12-19 20:25:09 +01:00
def create_main_partition(disk):
2021-12-20 15:32:11 +01:00
print("Create main partition.")
2021-12-20 16:58:20 +01:00
_run_command(["parted", "--script", disk, "mkpart",
2021-12-23 11:22:42 +01:00
"primary", "512MiB", "100%"])
2021-12-19 20:25:09 +01:00
return "{}{}2".format(disk, _partition_suffix(disk))
2021-12-20 15:58:11 +01:00
def _create_main_filesystem():
2021-12-19 20:10:49 +01:00
_run_command(["lvcreate", "-l", "100%FREE", "MainGroup", "-n", "root"])
_run_command(["mkfs.ext4", "-L", "nixos", "/dev/MainGroup/root"])
2021-12-19 18:41:03 +01:00
2021-12-19 20:25:09 +01:00
def _create_swap():
2021-12-19 20:10:49 +01:00
memory = _get_system_memory()
print("Create swap partition of {} GiB in size".format(memory))
_run_command(["lvcreate",
"-L",
"{}G".format(memory),
"MainGroup",
"-n",
"swap"])
_run_command(["mkswap", "-L", "swap", "/dev/MainGroup/swap"])
2021-12-19 18:41:03 +01:00
2021-12-19 20:10:49 +01:00
2021-12-23 11:22:42 +01:00
def _encrypt_disk(partition_path):
2021-12-20 10:41:11 +01:00
password = getpass.getpass()
2021-12-19 18:41:03 +01:00
print("Encrypting disk.")
2021-12-20 15:56:33 +01:00
_run_command(["cryptsetup", "luksFormat", "-q",
2021-12-23 11:22:42 +01:00
"--type", "luks1", partition_path], user_input=password)
_run_command(["cryptsetup", "open", partition_path, "cryptlvm"], user_input=password)
2021-12-19 20:10:49 +01:00
2021-12-19 18:41:03 +01:00
2021-12-19 20:10:49 +01:00
def _setup_lvm(lvm_target):
2021-12-20 19:20:39 +01:00
print("Set up LVM on {}.".format(lvm_target))
2021-12-19 20:10:49 +01:00
_run_command(["pvcreate", lvm_target])
_run_command(["vgcreate", "MainGroup", lvm_target])
2021-12-19 18:41:03 +01:00
2021-12-19 20:10:49 +01:00
def mount_partitions():
2021-12-20 15:32:11 +01:00
print("Mounting partitions.")
2021-12-19 20:10:49 +01:00
_run_command(["mount", "/dev/MainGroup/root", "/mnt"])
os.mkdir("/mnt/boot")
_run_command(["mount", "/dev/disk/by-label/BOOT", "/mnt/boot"])
2021-12-19 20:25:09 +01:00
def create_file_systems(partition, swap, encryption):
print("Creating filesystems.")
2021-12-19 20:10:49 +01:00
if encryption:
lvm_target = "/dev/mapper/cryptlvm"
2021-12-23 11:22:42 +01:00
_encrypt_disk(partition)
2021-12-19 20:10:49 +01:00
else:
2021-12-19 20:25:09 +01:00
lvm_target = partition
2021-12-19 20:10:49 +01:00
_setup_lvm(lvm_target)
2021-12-19 20:25:09 +01:00
if swap:
_create_swap()
_create_main_filesystem()
2021-12-19 18:41:03 +01:00
def main():
2021-12-19 18:47:36 +01:00
disks = read_disks()
2021-12-19 18:48:18 +01:00
create_menu(disks)
disk_to_format = disks[get_disk_to_format()]
2021-12-19 20:25:09 +01:00
swap = _y_n("Do you need swap?")
2021-12-19 20:16:49 +01:00
encryption = _y_n("Do you want to encrypt your data?")
2021-12-20 12:24:33 +01:00
create_partition_table(disk_to_format)
2021-12-19 20:10:49 +01:00
create_boot_partition(disk_to_format)
2021-12-19 20:25:09 +01:00
main_partition = create_main_partition(disk_to_format)
create_file_systems(main_partition, swap, encryption)
2021-12-19 20:10:49 +01:00
mount_partitions()
2021-12-19 18:41:03 +01:00
if __name__ == "__main__":
main()