Last active
November 20, 2024 07:54
-
-
Save dzogrim/19e34bcb0a20d10dc696e6b20930d06b to your computer and use it in GitHub Desktop.
The script deploys a NixOS system by writing an image file (disk.raw) to a target disk (/dev/nvme0n1) using dd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# This script deploys a pre-configured NixOS image from an NTFS device | |
# to a specified disk, ensuring robust error handling and user confirmations. | |
# It validates necessary tools, verifies mount points, and optionally checks | |
# SHA256 checksums for the image. Deployment overwrites all data on the target | |
# disk, with a power-off mechanism post-deployment unless canceled. | |
# Designed for Linux-based live USB environments like SystemRescue. | |
# VERSION=2024-11-20 | |
# Variables | |
MOUNT_DIR="/mnt/DATA" | |
DEVICE="/dev/sda3" | |
RAW_FILE="${MOUNT_DIR}/image.raw" | |
TARGET_DISK="/dev/nvme0n1" | |
# Define ANSI color codes (POSIX-compatible) | |
# Will works only in compatible terms! | |
RED='\033[31m' | |
YELLOW='\033[33m' | |
GREEN='\033[32m' | |
# No Color (reset) | |
NC='\033[0m' | |
# Function to print error messages and exit | |
error_exit() { | |
printf "${RED}Error: %s${NC}\\n" "$1" >&2 | |
exit 1 | |
} | |
# Function to print warning messages | |
warn_msg() { | |
printf "${YELLOW}Warning: %s${NC}\\n" "$1" | |
} | |
# Function to print success messages | |
success_msg() { | |
printf "$GREEN%s$NC\\n" "$1" | |
} | |
# Ensure the script runs as root | |
[ "$(id -u)" -eq 0 ] || error_exit "This script must be run as root." | |
# Ensure the system have required tools | |
required_tools="dd mount.ntfs-3g sha256sum awk" | |
for tool in $required_tools; do | |
command -v "$tool" >/dev/null 2>&1 || \ | |
error_exit "$tool is not installed. Please install it first." | |
done | |
success_msg "All required tools are installed." | |
# Create the mount directory if it doesn't exist | |
if [ ! -d "$MOUNT_DIR" ]; then | |
printf "Creating mount directory: %s\n" "$MOUNT_DIR" | |
mkdir -p "$MOUNT_DIR" || error_exit "Failed to create mount directory." | |
fi | |
# Check if the device exists | |
[ -b "$DEVICE" ] || error_exit "Device $DEVICE does not exist." | |
# Check if the directory is already mounted | |
if mount | grep -q "on $MOUNT_DIR type"; then | |
success_msg "${MOUNT_DIR} is already mounted. Skipping mount step." | |
else | |
printf "Mounting %s to %s ...\n" $DEVICE $MOUNT_DIR | |
if mount.ntfs-3g "$DEVICE" "$MOUNT_DIR"; then | |
printf "Successfully mounted %s to %s.\n" $DEVICE $MOUNT_DIR | |
else | |
error_exit "Failed to mount ${DEVICE}." | |
fi | |
fi | |
# Verify the mount was successful | |
if mount | grep -q "on $MOUNT_DIR type"; then | |
printf "Verification: %s is mounted on %s.\n" "$DEVICE" "$MOUNT_DIR" | |
else | |
error_exit "Mount verification failed. $DEVICE may not be properly mounted." | |
fi | |
# Check if the disk.raw file exists | |
if [ -f "$RAW_FILE" ]; then | |
# Perform SHA256 checksum verification if the .sha256 file exists | |
if [ -f "${RAW_FILE}.sha256" ]; then | |
printf "Verifying the checksum of %s ...\n" "$RAW_FILE" | |
calculated_checksum=$(sha256sum "$RAW_FILE" | awk '{print $1}') | |
trusted_checksum=$(cat "${RAW_FILE}.sha256" | awk '{print $1}') | |
if [ "$calculated_checksum" = "$trusted_checksum" ]; then | |
success_msg "Checksum verification passed." | |
else | |
printf "${RED}ERROR${NC}: Checksum verification failed!\n" | |
printf "Calculated: %s\n" "$calculated_checksum" | |
printf "Expected: %s\n" "$trusted_checksum" | |
exit 1 | |
fi | |
else | |
warn_msg "No '.raw.sha256' file found. Skipping checksum verification." | |
printf "You should have this warning in mind and abort the process right now!\n" | |
fi | |
# Continue with the deployment | |
printf "${RED}WARNING: ${NC}You are about to deploy NixOS to %s!\n" "$TARGET_DISK" | |
printf "${RED}This action will overwrite ALL data on internal device %s.${NC}\n" "$TARGET_DISK" | |
printf "Are you sure you want to proceed? (yes/no): " | |
read -r response | |
if [ "$response" = "yes" ]; then | |
printf "Starting deployment ...\n" | |
if dd if="$RAW_FILE" of="$TARGET_DISK" bs=4M status=progress ; then | |
sync | |
success_msg "Deployment completed successfully." | |
success_msg "The system will power off in 10 seconds unless you press any key." | |
# Wait for 8 seconds for any key press | |
printf "Press any key to cancel power off ... " | |
read -r -t 8 key && printf "\nPower off canceled.\n" || { | |
printf "\nPowering off ...\n" | |
poweroff | |
} | |
else | |
error_exit "Deployment failed. Please check your devices and the image file." | |
fi | |
else | |
printf "Deployment aborted.\n" | |
fi | |
else | |
printf "The file %s does not exist. Exiting ...\n" "$RAW_FILE" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment