Public repo to distribute scripts and config's
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 

270 lignes
8.7 KiB

  1. #!/bin/bash
  2. # Enable strict error handling
  3. set -e
  4. # Function to log messages with timestamps
  5. log() {
  6. echo "$(date '+%F %T') - $@"
  7. }
  8. # Function to display usage information
  9. usage() {
  10. echo "Usage: $0 [-d DEVICE] [-f FARM] [-e ENVIRONMENT]"
  11. echo " -d, --device DEVICE Specify the block device to use (e.g., sda, nvme0n1)."
  12. echo " -f, --farm FARM Specify the FARM ID."
  13. echo " -e, --environment ENV Specify the environment (dev, qa, test, prod)."
  14. echo " -h, --help Display this help message."
  15. exit 1
  16. }
  17. # Function to find a suitable block device
  18. find_blockdev() {
  19. # Minimum size in bytes, e.g., 10 GiB
  20. MIN_SIZE=$((10 * 1024 * 1024 * 1024))
  21. # Search for NVMe devices first
  22. log "Searching for NVMe devices..."
  23. for DEV in /dev/nvme*n1; do
  24. if [ -b "$DEV" ]; then
  25. SIZE_BYTES=$(blockdev --getsize64 "$DEV")
  26. if [ "$SIZE_BYTES" -ge "$MIN_SIZE" ]; then
  27. log "Found NVMe device: $DEV ($(numfmt --to=iec $SIZE_BYTES))"
  28. BLOCKDEV="${DEV##*/}"
  29. return 0
  30. else
  31. log "$DEV is smaller than $(numfmt --to=iec $MIN_SIZE). Skipping."
  32. fi
  33. fi
  34. done
  35. # If no NVMe device found, search for SSD devices
  36. log "No suitable NVMe device found. Searching for SSD devices..."
  37. for DEV_PATH in /sys/block/*; do
  38. DEV_NAME=$(basename "$DEV_PATH")
  39. # Exclude unwanted devices
  40. case "$DEV_NAME" in
  41. loop*|ram*|sr*|fd*|md*|dm-*)
  42. continue
  43. ;;
  44. esac
  45. DEVICE="/dev/$DEV_NAME"
  46. if [ -b "$DEVICE" ] && [ -e "/sys/block/$DEV_NAME/queue/rotational" ] && [ "$(cat /sys/block/$DEV_NAME/queue/rotational)" == "0" ]; then
  47. SIZE_BYTES=$(blockdev --getsize64 "$DEVICE")
  48. if [ "$SIZE_BYTES" -ge "$MIN_SIZE" ]; then
  49. log "Found SSD device: $DEVICE ($(numfmt --to=iec $SIZE_BYTES))"
  50. BLOCKDEV="$DEV_NAME"
  51. return 0
  52. else
  53. log "$DEVICE is smaller than $(numfmt --to=iec $MIN_SIZE). Skipping."
  54. fi
  55. fi
  56. done
  57. log "No suitable block device found."
  58. return 1
  59. }
  60. # Function to manage UEFI boot entries
  61. manage_boot_entries() {
  62. log "Managing UEFI boot entries..."
  63. # Check if efibootmgr is available
  64. if ! command -v efibootmgr &> /dev/null; then
  65. log "Error: 'efibootmgr' is not installed. Please install it and rerun the script."
  66. exit 1
  67. fi
  68. # Get the list of current boot entries
  69. CURRENT_BOOT_ENTRIES=$(efibootmgr | grep "BootOrder")
  70. log "Current BootOrder: $CURRENT_BOOT_ENTRIES"
  71. # Delete all existing boot entries except the EFI Shell (if present)
  72. log "Deleting existing boot entries..."
  73. BOOT_ENTRIES=$(efibootmgr | grep -E "^Boot[0-9A-F]{4}" | awk '{print $1}' | sed 's/\*//')
  74. for ENTRY in $BOOT_ENTRIES; do
  75. efibootmgr -b ${ENTRY#Boot} -B
  76. log "Deleted boot entry $ENTRY"
  77. done
  78. # Create a new boot entry pointing to BOOTX64.EFI on the first partition
  79. log "Creating new boot entry for /dev/${PARTPREFIX}1..."
  80. # Adjust the partition number if necessary
  81. ESP_PART_NUM=1
  82. efibootmgr -c -d /dev/${BLOCKDEV} -p $ESP_PART_NUM -L "Zero-OS" -l "\\EFI\\BOOT\\BOOTX64.EFI" || {
  83. log "Error: Failed to create new boot entry."
  84. exit 1
  85. }
  86. # Set the boot order to include only the new boot entry
  87. NEW_BOOT_NUM=$(efibootmgr | grep "Zero-OS" | awk '{print $1}' | sed 's/\*//;s/Boot//')
  88. if [ -z "$NEW_BOOT_NUM" ]; then
  89. log "Error: Failed to retrieve new boot entry number."
  90. exit 1
  91. fi
  92. log "Setting BootOrder to only include Boot$NEW_BOOT_NUM..."
  93. efibootmgr -o $NEW_BOOT_NUM || {
  94. log "Error: Failed to set new BootOrder."
  95. exit 1
  96. }
  97. log "New BootOrder set successfully."
  98. }
  99. # Main script execution
  100. main() {
  101. # Default values
  102. BLOCKDEV_SPECIFIED=""
  103. FARM="1234"
  104. ENVIRONMENT="prod"
  105. # Parse command-line arguments
  106. while [[ $# -gt 0 ]]; do
  107. case "$1" in
  108. -d|--device)
  109. shift
  110. if [ -z "$1" ]; then
  111. log "Error: '--device' requires a non-empty option argument."
  112. usage
  113. fi
  114. BLOCKDEV_SPECIFIED="$1"
  115. shift
  116. ;;
  117. -f|--farm)
  118. shift
  119. if [ -z "$1" ]; then
  120. log "Error: '--farm' requires a non-empty option argument."
  121. usage
  122. fi
  123. FARM="$1"
  124. shift
  125. ;;
  126. -e|--environment)
  127. shift
  128. if [ -z "$1" ]; then
  129. log "Error: '--environment' requires a non-empty option argument."
  130. usage
  131. fi
  132. ENVIRONMENT="$1"
  133. shift
  134. ;;
  135. -h|--help)
  136. usage
  137. ;;
  138. *)
  139. log "Error: Unknown option: $1"
  140. usage
  141. ;;
  142. esac
  143. done
  144. # Validate environment
  145. case "$ENVIRONMENT" in
  146. dev|qa|test|prod)
  147. log "Using environment: $ENVIRONMENT"
  148. ;;
  149. *)
  150. log "Error: Invalid environment '$ENVIRONMENT'. Valid options are 'dev', 'qa', 'test', 'prod'."
  151. exit 1
  152. ;;
  153. esac
  154. if [ -n "$BLOCKDEV_SPECIFIED" ]; then
  155. # Use the specified block device
  156. if [[ "$BLOCKDEV_SPECIFIED" != /dev/* ]]; then
  157. BLOCKDEV_SPECIFIED="/dev/$BLOCKDEV_SPECIFIED"
  158. fi
  159. if [ ! -b "$BLOCKDEV_SPECIFIED" ]; then
  160. log "Error: Specified device $BLOCKDEV_SPECIFIED does not exist or is not a block device."
  161. exit 1
  162. fi
  163. BLOCKDEV="${BLOCKDEV_SPECIFIED##*/}"
  164. log "Using specified block device: $BLOCKDEV_SPECIFIED"
  165. else
  166. # Find a suitable block device
  167. if ! find_blockdev; then
  168. log "Error: No suitable block device found."
  169. exit 1
  170. fi
  171. log "Selected block device: /dev/${BLOCKDEV}"
  172. fi
  173. # Confirm with the user before proceeding
  174. read -p "This will erase all data on /dev/${BLOCKDEV}. Are you sure you want to proceed? (yes/[no]): " CONFIRM
  175. if [ "$CONFIRM" != "yes" ]; then
  176. log "Operation cancelled by user."
  177. exit 0
  178. fi
  179. # Determine partition naming convention
  180. if [[ $BLOCKDEV =~ [0-9]$ ]]; then
  181. PARTPREFIX="${BLOCKDEV}p"
  182. else
  183. PARTPREFIX="${BLOCKDEV}"
  184. fi
  185. # Wipe filesystem signatures
  186. log "Wiping filesystem signatures on /dev/${BLOCKDEV}..."
  187. wipefs -a -f /dev/${BLOCKDEV} || { log "Failed to wipe filesystem signatures."; exit 1; }
  188. # Create GPT partition table
  189. log "Creating GPT partition table on /dev/${BLOCKDEV}..."
  190. parted -s /dev/${BLOCKDEV} mklabel gpt || { log "Failed to create GPT partition table."; exit 1; }
  191. # Create partitions
  192. log "Creating partitions on /dev/${BLOCKDEV}..."
  193. if ! parted -s /dev/${BLOCKDEV} "mkpart zosboot fat32 1MiB 300MiB set 1 esp on mkpart zoscache btrfs 300MiB 100%"; then
  194. log "Failed to create partitions."
  195. exit 1
  196. fi
  197. # Format partitions
  198. log "Formatting /dev/${PARTPREFIX}1 as FAT32..."
  199. if ! mkfs.vfat -F32 /dev/${PARTPREFIX}1; then
  200. log "Failed to format /dev/${PARTPREFIX}1 as FAT32."
  201. exit 1
  202. fi
  203. log "Formatting /dev/${PARTPREFIX}2 as BTRFS..."
  204. if ! mkfs.btrfs -f /dev/${PARTPREFIX}2; then
  205. log "Failed to format /dev/${PARTPREFIX}2 as BTRFS."
  206. exit 1
  207. fi
  208. # Mount and prepare directories
  209. MOUNT_POINT="zospxe"
  210. log "Creating and mounting directory ./${MOUNT_POINT}..."
  211. mkdir -p "${MOUNT_POINT}"
  212. if ! mount /dev/${PARTPREFIX}1 -t vfat "${MOUNT_POINT}"; then
  213. log "Failed to mount /dev/${PARTPREFIX}1 to ${MOUNT_POINT}."
  214. exit 1
  215. fi
  216. log "Creating directory structure in ${MOUNT_POINT}..."
  217. mkdir -p "${MOUNT_POINT}/efi/boot"
  218. # Download the required BOOTX64.EFI file
  219. # NOTE:: EDIT THIS WHEN APPROPRIATE AND IN PROD
  220. EFI_FILE_URL="https://bootstrap.grid.tf/uefi/${ENVIRONMENT}/${FARM}/debug/zero-os-development-zos-v4-debug-7d2de62033.efi?version=v4"
  221. # EFI_FILE_URL="https://bootstrap.grid.tf/uefi/${ENVIRONMENT}/${FARM}"
  222. log "Downloading BOOTX64.EFI from ${EFI_FILE_URL}..."
  223. if ! wget -q "${EFI_FILE_URL}" -O "${MOUNT_POINT}/efi/boot/BOOTX64.EFI"; then
  224. log "Failed to download BOOTX64.EFI."
  225. exit 1
  226. fi
  227. log "Download successful."
  228. # Unmount the partition
  229. log "Unmounting ${MOUNT_POINT}..."
  230. umount -r "${MOUNT_POINT}" || { log "Failed to unmount ${MOUNT_POINT}."; exit 1; }
  231. # Manage UEFI boot entries
  232. manage_boot_entries
  233. log "Operation completed successfully."
  234. }
  235. # Execute the main function
  236. main "$@"