Skip to content

Instantly share code, notes, and snippets.

@dzogrim
Last active November 20, 2024 07:54
Show Gist options
  • Save dzogrim/19e34bcb0a20d10dc696e6b20930d06b to your computer and use it in GitHub Desktop.
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
#!/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