Unify the scripts to format disks
This commit is contained in:
parent
8cb97ad3fc
commit
a1e4d0ae67
19
README.md
19
README.md
|
@ -4,24 +4,11 @@ This repository contains my configuration for my Nixos systems.
|
||||||
I don't provide any garantuees that it will work on other systems.
|
I don't provide any garantuees that it will work on other systems.
|
||||||
In addition some of the scripts required for installation will destroy your data when used.
|
In addition some of the scripts required for installation will destroy your data when used.
|
||||||
|
|
||||||
## Preparation
|
|
||||||
|
|
||||||
On a PC you don't have to do anything special.
|
|
||||||
|
|
||||||
For a Raspberry Pi you need to prepare the SD card first with a UEFI partition. On a PC navigate into this project and run the following commands:
|
|
||||||
|
|
||||||
- `nix-shell`
|
|
||||||
- `sudo create-uefi-partition.sh`
|
|
||||||
|
|
||||||
This will format the SD card at `/dev/mmcblk0`, create a partition and download and copy all the required files for running UEFI on a Pi 4.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Insert an USB stick with the latest NixOS ISO into your device.
|
1. For Raspis it's the easiest if you prepare the SD card/disk on another system. For a PC you can just boot the installation ISO directly.
|
||||||
1. `curl https://git.2li.ch/Nebucatnetzer/nixos/archive/master.tar.gz | tar xz`
|
1. For both devices you can format the disk/card with the following script `sudo ./scripts/format-disk.py`. It will walk you through the formatting process and for a Raspi4 it will prepare it for UEFI setup.
|
||||||
1. `cd nixos && nix-shell setup-shell.nix`
|
1. Next install the system with `sudo nixos-install --no-root-passwd --root /mnt/nixos --impure --flake .#SYSTEMNAME`
|
||||||
1. For a normal PC run: `sudo ./scripts/format-disk.py` on a Raspberry Pi 4 run: `sudo ./scripts/format-sdcard.py`
|
|
||||||
1. `sudo nixos-install --no-root-passwd --root /mnt --impure --flake .#SYSTEMNAME`
|
|
||||||
|
|
||||||
When everything is finished you can reboot the system and remove the USB stick. You have now a fully encrypted NixOS system.
|
When everything is finished you can reboot the system and remove the USB stick. You have now a fully encrypted NixOS system.
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ in {
|
||||||
boot.kernelParams = [ "rootflags=atgc" "rw" ];
|
boot.kernelParams = [ "rootflags=atgc" "rw" ];
|
||||||
|
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "/dev/disk/by-label/NixosSd";
|
device = "/dev/disk/by-label/NIXOSSD";
|
||||||
fsType = "f2fs";
|
fsType = "f2fs";
|
||||||
options = [
|
options = [
|
||||||
"atgc,gc_merge"
|
"atgc,gc_merge"
|
||||||
|
@ -77,7 +77,7 @@ in {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
device = "/dev/disk/by-label/SdBoot";
|
device = "/dev/disk/by-label/BOOT";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#! /usr/bin/env nix-shell
|
|
||||||
#! nix-shell -i bash -p parted unzip curl
|
|
||||||
|
|
||||||
# Create the boot partition
|
|
||||||
parted --script /dev/mmcblk0 mklabel gpt
|
|
||||||
parted --script /dev/mmcblk0 mkpart ESP fat32 0% 1GiB
|
|
||||||
parted --script /dev/mmcblk0 set 1 esp on
|
|
||||||
mkfs.fat -F32 -n SdBoot /dev/mmcblk0p1
|
|
||||||
|
|
||||||
# Download and install the UEFI firmware
|
|
||||||
mkdir -p /tmp/sdcard/boot
|
|
||||||
mount /dev/mmcblk0p1 /tmp/sdcard/boot
|
|
||||||
curl -o /tmp/pi4-uefi.zip -L https://github.com/pftf/RPi4/releases/download/v1.35/RPi4_UEFI_Firmware_v1.35.zip
|
|
||||||
unzip /tmp/pi4-uefi.zip -d /tmp/sdcard/boot
|
|
||||||
sync
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
umount /tmp/sdcard/boot
|
|
||||||
rm /tmp/pi4-uefi.zip
|
|
|
@ -1,10 +1,15 @@
|
||||||
#! /usr/bin/env nix-shell
|
#! /usr/bin/env nix-shell
|
||||||
#! nix-shell -i python3 -p python3
|
#! nix-shell -i python3 -p python3 parted
|
||||||
|
|
||||||
import getpass
|
import getpass
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
from urllib.request import urlretrieve
|
||||||
|
|
||||||
|
|
||||||
def _run_command(command, user_input=""):
|
def _run_command(command, user_input=""):
|
||||||
|
@ -56,91 +61,135 @@ def get_disk_to_format():
|
||||||
def create_partition_table(disk):
|
def create_partition_table(disk):
|
||||||
print("Create partition table.")
|
print("Create partition table.")
|
||||||
_run_command(["parted", "--script", disk, "mklabel", "gpt"])
|
_run_command(["parted", "--script", disk, "mklabel", "gpt"])
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
|
||||||
def _partition_suffix(disk):
|
def _partition_suffix(disk):
|
||||||
if "nvmne" in disk:
|
prefixes = ["nvmne", "mmc"]
|
||||||
|
if any(prefix in disk for prefix in prefixes):
|
||||||
return "p"
|
return "p"
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _get_uefi():
|
||||||
|
filename = "RPi4_UEFI_Firmware_v1.35.zip"
|
||||||
|
url = f"https://github.com/pftf/RPi4/releases/download/v1.35/{filename}"
|
||||||
|
retrieved_file, _ = urlretrieve(url, f"/tmp/{filename}")
|
||||||
|
return retrieved_file
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_uefi(path_to_zip, partition):
|
||||||
|
with zipfile.ZipFile(path_to_zip, "r") as zip_ref:
|
||||||
|
zip_ref.extractall(partition)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_uefi():
|
||||||
|
print("Create UEFI partition.")
|
||||||
|
filename = _get_uefi()
|
||||||
|
_extract_uefi(filename, "/mnt/nixos/boot")
|
||||||
|
|
||||||
|
|
||||||
def create_boot_partition(disk):
|
def create_boot_partition(disk):
|
||||||
boot_partition = "{}{}1".format(disk, _partition_suffix(disk))
|
boot_partition = "{}{}1".format(disk, _partition_suffix(disk))
|
||||||
print("Create boot partition {}.".format(boot_partition))
|
print("Create boot partition {}.".format(boot_partition))
|
||||||
_run_command(
|
_run_command(["parted", "--script", disk, "mkpart", "ESP", "fat32", "0%", "1GiB"])
|
||||||
["parted", "--script", disk, "mkpart", "ESP", "fat32", "1MiB", "512MiB"]
|
|
||||||
)
|
|
||||||
_run_command(["parted", "--script", disk, "set", "1", "esp", "on"])
|
_run_command(["parted", "--script", disk, "set", "1", "esp", "on"])
|
||||||
_run_command(["mkfs.fat", "-F", "32", "-n", "BOOT", boot_partition])
|
_run_command(["mkfs.fat", "-F", "32", "-n", "BOOTTOFRMT", boot_partition])
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
|
||||||
def create_main_partition(disk):
|
def create_main_partition(disk):
|
||||||
print("Create main partition.")
|
print("Create main partition.")
|
||||||
_run_command(["parted", "--script", disk, "mkpart", "primary", "512MiB", "100%"])
|
_run_command(["parted", "--script", disk, "mkpart", "primary", "1GiB", "100%"])
|
||||||
return "{}{}2".format(disk, _partition_suffix(disk))
|
return "{}{}2".format(disk, _partition_suffix(disk))
|
||||||
|
|
||||||
|
|
||||||
def _create_main_filesystem():
|
def _create_ext4():
|
||||||
_run_command(["lvcreate", "-l", "100%FREE", "MainGroup", "-n", "root"])
|
_run_command(["lvcreate", "-l", "100%FREE", "grouptoformat", "-n", "ROOTTOFRMT"])
|
||||||
_run_command(["mkfs.ext4", "-L", "nixos", "/dev/MainGroup/root"])
|
_run_command(["mkfs.ext4", "-L", "ROOTTOFRMT", "/dev/grouptoformat/ROOTTOFRMT"])
|
||||||
|
|
||||||
|
|
||||||
|
def _create_f2fs():
|
||||||
|
_run_command(["mkfs.f2fs", "-l", "ROOTTOFRMT", "/dev/mapper/crypttoformat"])
|
||||||
|
|
||||||
|
|
||||||
def _create_swap():
|
def _create_swap():
|
||||||
memory = _get_system_memory()
|
memory = _get_system_memory()
|
||||||
print("Create swap partition of {} GiB in size".format(memory))
|
print("Create swap partition of {} GiB in size".format(memory))
|
||||||
_run_command(["lvcreate", "-L", "{}G".format(memory), "MainGroup", "-n", "swap"])
|
_run_command(
|
||||||
_run_command(["mkswap", "-L", "swap", "/dev/MainGroup/swap"])
|
["lvcreate", "-L", "{}G".format(memory), "grouptoformat", "-n", "SWAPTOFRMT"]
|
||||||
|
)
|
||||||
|
_run_command(["mkswap", "-L", "SWAPTOFRMT", "/dev/grouptoformat/SWAPTOFRMT"])
|
||||||
|
|
||||||
|
|
||||||
def _encrypt_disk(partition_path):
|
def _encrypt_disk(partition_path):
|
||||||
password = getpass.getpass()
|
password = getpass.getpass()
|
||||||
print("Encrypting disk.")
|
print("Encrypting disk.")
|
||||||
_run_command(
|
_run_command(
|
||||||
["cryptsetup", "luksFormat", "-q", "--type", "luks1", partition_path],
|
["cryptsetup", "luksFormat", "-q", partition_path],
|
||||||
user_input=password,
|
user_input=password,
|
||||||
)
|
)
|
||||||
_run_command(
|
_run_command(
|
||||||
["cryptsetup", "open", partition_path, "cryptlvm"], user_input=password
|
["cryptsetup", "open", partition_path, "crypttoformat"], user_input=password
|
||||||
)
|
)
|
||||||
|
return "/dev/mapper/crypttoformat"
|
||||||
|
|
||||||
|
|
||||||
def _setup_lvm(lvm_target):
|
def _setup_lvm(lvm_target):
|
||||||
print("Set up LVM on {}.".format(lvm_target))
|
print("Set up LVM on {}.".format(lvm_target))
|
||||||
_run_command(["pvcreate", lvm_target])
|
_run_command(["pvcreate", lvm_target])
|
||||||
_run_command(["vgcreate", "MainGroup", lvm_target])
|
_run_command(["vgcreate", "grouptoformat", lvm_target])
|
||||||
|
|
||||||
|
|
||||||
def mount_partitions():
|
def mount_partitions(
|
||||||
|
root_src="/dev/disk/by-label/ROOTTOFRMT",
|
||||||
|
boot_src="/dev/disk/by-label/BOOTTOFRMT",
|
||||||
|
root_target="/mnt/nixos",
|
||||||
|
boot_target="/mnt/nixos/boot",
|
||||||
|
):
|
||||||
print("Mounting partitions.")
|
print("Mounting partitions.")
|
||||||
_run_command(["mount", "/dev/MainGroup/root", "/mnt"])
|
sleep(5)
|
||||||
os.mkdir("/mnt/boot")
|
os.makedirs(root_target, exist_ok=True)
|
||||||
_run_command(["mount", "/dev/disk/by-label/BOOT", "/mnt/boot"])
|
_run_command(["mount", root_src, root_target])
|
||||||
|
os.makedirs(boot_target, exist_ok=True)
|
||||||
|
_run_command(["mount", boot_src, boot_target])
|
||||||
|
|
||||||
|
|
||||||
def create_file_systems(partition, swap, encryption):
|
def create_pc(partition, swap, encryption):
|
||||||
print("Creating filesystems.")
|
print("Creating filesystems.")
|
||||||
if encryption:
|
if encryption:
|
||||||
lvm_target = "/dev/mapper/cryptlvm"
|
lvm_target = "/dev/mapper/crypttoformat"
|
||||||
_encrypt_disk(partition)
|
_encrypt_disk(partition)
|
||||||
else:
|
else:
|
||||||
lvm_target = partition
|
lvm_target = partition
|
||||||
_setup_lvm(lvm_target)
|
_setup_lvm(lvm_target)
|
||||||
if swap:
|
if swap:
|
||||||
_create_swap()
|
_create_swap()
|
||||||
_create_main_filesystem()
|
_create_ext4()
|
||||||
|
|
||||||
|
|
||||||
|
def create_raspi(main_partition):
|
||||||
|
print("Create filesystems.")
|
||||||
|
_encrypt_disk(main_partition)
|
||||||
|
_create_f2fs()
|
||||||
|
mount_partitions()
|
||||||
|
_create_uefi()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
disks = read_disks()
|
disks = read_disks()
|
||||||
create_menu(disks)
|
create_menu(disks)
|
||||||
disk_to_format = disks[get_disk_to_format()]
|
disk_to_format = disks[get_disk_to_format()]
|
||||||
swap = _y_n("Do you need swap?")
|
raspi = _y_n("Do you want to setup a Raspi?")
|
||||||
encryption = _y_n("Do you want to encrypt your data?")
|
|
||||||
create_partition_table(disk_to_format)
|
create_partition_table(disk_to_format)
|
||||||
create_boot_partition(disk_to_format)
|
create_boot_partition(disk_to_format)
|
||||||
main_partition = create_main_partition(disk_to_format)
|
main_partition = create_main_partition(disk_to_format)
|
||||||
create_file_systems(main_partition, swap, encryption)
|
if raspi:
|
||||||
mount_partitions()
|
create_raspi(main_partition)
|
||||||
|
else:
|
||||||
|
swap = _y_n("Do you need swap?")
|
||||||
|
encryption = _y_n("Do you need encryption?")
|
||||||
|
create_pc(main_partition, swap, encryption)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
#! /usr/bin/env nix-shell
|
|
||||||
#! nix-shell -i python3 -p python3 parted
|
|
||||||
|
|
||||||
import getpass
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
def _run_command(command, user_input=""):
|
|
||||||
if user_input:
|
|
||||||
result = subprocess.run(
|
|
||||||
command, capture_output=True, text=True, check=True, input=user_input
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
result = subprocess.run(command, capture_output=True, text=True, check=True)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def _partition_suffix(disk):
|
|
||||||
if ("nvmne" or "mmc") in disk:
|
|
||||||
return "p"
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def read_disks():
|
|
||||||
output = _run_command(["lsblk", "-dpno", "name"])
|
|
||||||
disks = []
|
|
||||||
for disk in output.stdout.splitlines():
|
|
||||||
if "loop" in disk:
|
|
||||||
continue
|
|
||||||
disks.append(disk)
|
|
||||||
return disks
|
|
||||||
|
|
||||||
|
|
||||||
def create_menu(disks):
|
|
||||||
for position, disk in enumerate(disks):
|
|
||||||
print("{}: {}".format(position, disk))
|
|
||||||
|
|
||||||
|
|
||||||
def get_disk_to_format():
|
|
||||||
disk_to_format = input("Which disk dou you want to format?: ")
|
|
||||||
return int(disk_to_format)
|
|
||||||
|
|
||||||
|
|
||||||
def create_main_partition(disk):
|
|
||||||
print("Create main partition.")
|
|
||||||
_run_command(["parted", "--script", disk, "mkpart", "primary", "1GiB", "100%"])
|
|
||||||
return f"{disk}{_partition_suffix(disk)}2"
|
|
||||||
|
|
||||||
|
|
||||||
def _create_main_filesystem():
|
|
||||||
_run_command(
|
|
||||||
[
|
|
||||||
"mkfs.f2fs",
|
|
||||||
"-l",
|
|
||||||
"NixosSd",
|
|
||||||
"-O",
|
|
||||||
"extra_attr,inode_checksum,sb_checksum,compression",
|
|
||||||
"/dev/mapper/cryptsd",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _encrypt_disk(partition_path):
|
|
||||||
password = getpass.getpass()
|
|
||||||
print("Encrypting disk.")
|
|
||||||
_run_command(
|
|
||||||
["cryptsetup", "luksFormat", "-q", partition_path],
|
|
||||||
user_input=password,
|
|
||||||
)
|
|
||||||
_run_command(["cryptsetup", "open", partition_path, "cryptsd"], user_input=password)
|
|
||||||
|
|
||||||
|
|
||||||
def create_file_systems(partition):
|
|
||||||
print("Creating filesystems.")
|
|
||||||
_encrypt_disk(partition)
|
|
||||||
_create_main_filesystem()
|
|
||||||
|
|
||||||
|
|
||||||
def mount_partitions():
|
|
||||||
print("Mounting partitions.")
|
|
||||||
_run_command(["mount", "/dev/disk/by-label/NixosSd", "/mnt"])
|
|
||||||
os.mkdir("/mnt/boot")
|
|
||||||
_run_command(["mount", "/dev/disk/by-label/SdBoot", "/mnt/boot"])
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
disks = read_disks()
|
|
||||||
create_menu(disks)
|
|
||||||
disk_to_format = disks[get_disk_to_format()]
|
|
||||||
main_partition = create_main_partition(disk_to_format)
|
|
||||||
create_file_systems(main_partition)
|
|
||||||
mount_partitions()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i python3 -p python3 parted
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
|
def _run_command(command, user_input=""):
|
||||||
|
if user_input:
|
||||||
|
result = subprocess.run(
|
||||||
|
command, capture_output=True, text=True, check=True, input=user_input
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
result = subprocess.run(command, capture_output=True, text=True, check=True)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _y_n(question):
|
||||||
|
answer = input("{} (Y/N): ".format(question))
|
||||||
|
if answer.lower() == "y":
|
||||||
|
return True
|
||||||
|
if answer.lower() == "n":
|
||||||
|
return False
|
||||||
|
print("Please only answer with Y or N!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def rename_boot_partition():
|
||||||
|
print("Rename boot partition.")
|
||||||
|
_run_command(["fatlabel", "/dev/disk/by-label/BOOTTOFRMT", "BOOT"])
|
||||||
|
|
||||||
|
|
||||||
|
def _rename_ext4():
|
||||||
|
print("Rename ext4 partition.")
|
||||||
|
_run_command(["e2label", "/dev/MainGroup/roottoformat", "root"])
|
||||||
|
|
||||||
|
|
||||||
|
def _rename_f2fs():
|
||||||
|
print("Rename f2fs partition.")
|
||||||
|
_run_command(["f2fslabel", "/dev/disk/by-label/ROOTTOFRMT", "root"])
|
||||||
|
|
||||||
|
|
||||||
|
def _rename_swap():
|
||||||
|
print("Rename swap partition.")
|
||||||
|
_run_command(["swaplabel", "-L", "swap", "/dev/GroupToFormat/swaptoformat"])
|
||||||
|
|
||||||
|
|
||||||
|
def _rename_lvm():
|
||||||
|
print("Rename LVM")
|
||||||
|
_run_command(["lvrename", "GroupToFormat", "roottoformat", "root"])
|
||||||
|
_run_command(["vgrename", "GroupToFormat", "MainGroup"])
|
||||||
|
|
||||||
|
|
||||||
|
def unmount_partitions():
|
||||||
|
print("Unmounting partitions.")
|
||||||
|
_run_command(["umount", "/mnt/nixos/boot"])
|
||||||
|
_run_command(["umount", "/mnt/nixos"])
|
||||||
|
sleep(3)
|
||||||
|
|
||||||
|
|
||||||
|
def close_luks():
|
||||||
|
_run_command(["cryptsetup", "close", "crypttoformat"])
|
||||||
|
|
||||||
|
|
||||||
|
def rename_pc(swap):
|
||||||
|
if swap:
|
||||||
|
_rename_swap()
|
||||||
|
_rename_ext4()
|
||||||
|
_rename_lvm()
|
||||||
|
|
||||||
|
|
||||||
|
def rename_raspi():
|
||||||
|
_rename_f2fs()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
raspi = _y_n("Do we rename a Raspberry Pi?")
|
||||||
|
unmount_partitions()
|
||||||
|
sleep(5)
|
||||||
|
rename_boot_partition()
|
||||||
|
if raspi:
|
||||||
|
rename_raspi()
|
||||||
|
else:
|
||||||
|
swap = _y_n("Do you have swap?")
|
||||||
|
rename_pc(swap)
|
||||||
|
close_luks()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue