372 lines
No EOL
11 KiB
Bash
Executable file
372 lines
No EOL
11 KiB
Bash
Executable file
#!/bin/bash
|
|
### Konstanten ###
|
|
|
|
declare -A GUIDS=""
|
|
GUIDS=([ESP]="c12a7328-f81f-11d2-ba4b-00a0c93ec93b" [USR]="8484680c-9521-48c6-9c11-b0720656f69e" [USRHASH]="77ff5f63-e7b6-4633-acf4-1565b864c0e6" [ROOT]="4f68bce3-e8cd-4db1-96e7-fbcaf984b709" [SWAP]="0657fd6d-a4ab-43c4-84e5-0933c84b4f4f")
|
|
|
|
### DEFAULTS ###
|
|
|
|
DEFAULT_DEVICE="/dev/sda"
|
|
DEFAULT_NAME="ArchOS"
|
|
DEFAULT_VERSION="0.1"
|
|
DEFAULT_ESP_SIZE="512M"
|
|
DEFAULT_ESP_LABEL="EFI System Partition"
|
|
DEFAULT_SWAP_SIZE="1G"
|
|
DEFAULT_ROOT_SIZE="5G"
|
|
DEFAULT_USR_SIZE="10G"
|
|
DEFAULT_USRHASH_SIZE="1G"
|
|
|
|
### Helper ###
|
|
|
|
# shellcheck disable=SC2059 # $1 and $2 can contain the printf modifiers
|
|
out() { printf "$1 $2\n" "${@:3}"; }
|
|
error() { out "==> ERROR:" "$@"; } >&2
|
|
warning() { out "==> WARNING:" "$@"; } >&2
|
|
msg() { out "==>" "$@"; }
|
|
die() { error "${@:2}"; exit "$1"; }
|
|
|
|
### Funktionen ###
|
|
|
|
help () {
|
|
echo "Aufruf:"
|
|
echo " ${0##*/} [Optionen]"
|
|
echo ""
|
|
echo "Erstellen eines Systems mit Read-Only /usr-Baum"
|
|
echo ""
|
|
echo "Optionen:"
|
|
echo " -f Partitionen erstellen, auch wenn sie vorhanden sind"
|
|
echo " -d <device> Dieses Gerät als Basis verwenden [${DEFAULT_DEVICE}]"
|
|
echo " -v <system-version> Version des neuen Systemes [${DEFAULT_VERSION}]"
|
|
echo " -n <name> Name des neuen Systems [${DEFAULT_NAME}]"
|
|
echo " -r <size> Größe der Root-Partition [${DEFAULT_ROOT_SIZE}]"
|
|
echo " -s <size> Größe der Swap-Partition [${DEFAULT_SWAP_SIZE}]"
|
|
echo " -u <size> Größe der Usr-Partition [${DEFAULT_USR_SIZE}]"
|
|
echo " -h Diese Hilfe anzeigen"
|
|
echo ""
|
|
echo "Exit-Code:"
|
|
echo " 1: Ein Fehler ist aufgetreten"
|
|
echo " 2: Üngültiges Argument"
|
|
echo " 3: Gerät existiert nicht"
|
|
echo " 10: Noch nicht implementiert"
|
|
echo ""
|
|
exit 0
|
|
}
|
|
|
|
# erase <Gerät>
|
|
erase () {
|
|
if [[ "$#" -eq 1 ]]; then
|
|
echo "dd if=/dev/zero of=$1 status=progress"
|
|
#dd if=/dev/zero of="$1" status=progress
|
|
echo "sgdisk -og $1"
|
|
#sgdisk -og "$1"
|
|
else
|
|
die 1 "Kein Gerät zum Löschen angegeben"
|
|
fi
|
|
}
|
|
|
|
# create <Type> <Gerät>
|
|
create () {
|
|
local TYPE="$1"
|
|
local DEVICE="$2"
|
|
case ${TYPE} in
|
|
"USR")
|
|
echo "sgdisk -n 0:0:+${USR_SIZE} -t 0:${GUIDS[USR]} -c 0:${USR_LABEL} ${DEVICE}"
|
|
#sgdisk -n 0:0:+"${USR_SIZE}" -t 0:"${GUIDS[USR]}" -c 0:"${USR_LABEL}" "${DEVICE}"
|
|
;;
|
|
"ROOT")
|
|
echo "sgdisk -n 0:0:+${ROOT_SIZE} -t 0:${GUIDS[ROOT]} -c 0:${ROOT_LABEL} ${DEVICE}"
|
|
#sgdisk -n 0:0:+"${ROOT_SIZE}" -t 0:"${GUIDS[ROOT]}" -c 0:"${ROOT_LABEL}" "${DEVICE}"
|
|
;;
|
|
"USRHASH")
|
|
echo "sgdisk -n 0:0:+${USRHASH_SIZE} -t 0:${GUIDS[USRHASH]} -c 0:${USRHASH_LABEL} ${DEVICE}"
|
|
#sgdisk -n 0:0:+"${USRHASH_SIZE}" -t 0:"${GUIDS[USRHASH]}" -c 0:"${USRHASH_LABEL}" "${DEVICE}"
|
|
;;
|
|
"ESP")
|
|
echo "sgdisk -n 0:0:+${ESP_SIZE} -t 0:${GUIDS[ESP]} -c 0:${ESP_LABEL} ${DEVICE}"
|
|
#sgdisk -n 0:0:+"${ESP_SIZE}" -t 0:"${GUIDS[ESP]}" -c 0:"${ESP_LABEL}" "${DEVICE}"
|
|
;;
|
|
"SWAP")
|
|
echo "sgdisk -n 0:0:+${SWAP_SIZE} -t 0:${GUIDS[SWAP]} -c 0:${SWAP_LABEL} ${DEVICE}"
|
|
#sgdisk -n 0:0:+"${SWAP_SIZE}" -t 0:"${GUIDS[SWAP]}" -c 0:"${SWAP_LABEL}" "${DEVICE}"
|
|
;;
|
|
"TABLE")
|
|
echo "sgdisk -og ${DEVICE}"
|
|
#sgdisk -og "${DEVICE}"
|
|
;;
|
|
*)
|
|
die 1 "Unbekannte Partition zum Erstellen angegeben"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# existing_partitions <Gerät> [<Type>]
|
|
existing_partitions () {
|
|
local DEVICE="$1"
|
|
local TYPE="$2"
|
|
if [[ $# -eq 1 ]] # Genereller test auf Partitionen
|
|
then
|
|
ANZAHL_PARTITIONEN_VORHANDEN=$(lsblk -pl "${DEVICE}" | grep -ic "${DEVICE}[0-9]")
|
|
if [[ ${ANZAHL_PARTITIONEN_VORHANDEN} != 0 ]]
|
|
then
|
|
echo "yes" # Partitionen vorhanden
|
|
else
|
|
echo "no" # Partitionen nicht vorhanden
|
|
fi
|
|
elif [[ $# -eq 2 ]] # Test auf eine bestimmte Partition
|
|
then
|
|
local PARTUUID="${GUIDS[${TYPE}]}" # Hier ist ein Problem
|
|
echo "PARTUUID: ${PARTUUID}" >> temp.log
|
|
SPEZIFISCHE_PARTITION_VORHANDEN=$(lsblk -o PARTTYPE "${DEVICE}" | grep -ic "${PARTUUID}")
|
|
if [[ "${SPEZIFISCHE_PARTITION_VORHANDEN}" == 1 ]]
|
|
then
|
|
echo "yes" # bestimmte Partition vorhanden
|
|
else
|
|
echo "no" # bestimmte Partition nicht vorhanden
|
|
fi
|
|
else
|
|
die 1 "Kein Gerät zur Prüfung auf Partitionen angegeben"
|
|
fi
|
|
}
|
|
|
|
# find_uuid_for_partition <Gerät> <Type>
|
|
find_uuid_for_partition () {
|
|
local DEVICE="$1"
|
|
local TYPE="$2"
|
|
if [[ "$(existing_partitions "${DEVICE}" "${TYPE}")" == "yes" ]]
|
|
then
|
|
uuid=$(lsblk -lo PARTTYPE,PARTUUID "${DEVICE}" | grep "${GUIDS[${TYPE}]}" | awk '{ print $2 }')
|
|
echo "${uuid}"
|
|
else
|
|
echo "null"
|
|
fi
|
|
}
|
|
|
|
# partitions_analyse <Gerät>
|
|
partitions_analyse () {
|
|
local DEVICE="$1"
|
|
local RESULT=""
|
|
declare -i index=""
|
|
index=0
|
|
for type in "${!GUIDS[@]}"
|
|
do
|
|
index+=1
|
|
uuid=$(find_uuid_for_partition "${DEVICE}" "${type}")
|
|
RESULT+="${type}=${uuid}"
|
|
if [[ "$index" != "${#GUIDS[@]}" ]]
|
|
then
|
|
RESULT+=" "
|
|
fi
|
|
done
|
|
echo "${RESULT}"
|
|
}
|
|
|
|
# print <analyse_result>
|
|
print () {
|
|
local ANALYSE_STRING="$1" # TYPE=([a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}) TYPE=null
|
|
echo "Typ UUID Geräte-Pfad" | awk '{ printf "| %-10s| %-40s| %-20s|\n", $1, $2, $3 }'
|
|
awk 'BEGIN { for(f=1; f<= 77; f++) { if( f==1 || f==13 || f==55 || f==77) { printf "|" } else { printf "-" } } printf "\n" }'
|
|
until [[ "${ANALYSE_STRING}" == "" ]]
|
|
do
|
|
local CURRENT_RESULT=$(echo "${ANALYSE_STRING}" | awk '{ print $1 }')
|
|
local CURRENT_TYPE=$(echo "${CURRENT_RESULT}" | awk 'BEGIN { FS="=" } { print $1 }')
|
|
local CURRENT_UUID=$(echo "${CURRENT_RESULT}" | awk 'BEGIN { FS="=" } { print $2 }')
|
|
local CURRENT_PATH=$(lsblk -plo NAME /dev/disk/by-partuuid/"${CURRENT_UUID}" 2> /dev/null | tail -n +2)
|
|
local CURRENT_REST=${ANALYSE_STRING//${CURRENT_RESULT}}
|
|
CURRENT_REST=${CURRENT_REST# }
|
|
echo "${CURRENT_TYPE} ${CURRENT_UUID} ${CURRENT_PATH}" | awk '{ printf "| %-10s| %-40s| %-20s|\n" , $1, $2 , $3 }'
|
|
ANALYSE_STRING="${CURRENT_REST# }"
|
|
done
|
|
echo ""
|
|
}
|
|
|
|
# print_todo <Gerät> <analyse_result>
|
|
print_todo () {
|
|
local DEVICE="$1"
|
|
local ANALYSE_STRING="$2"
|
|
echo "Bitte Partitionen mit dem folgenden Eigenschaften anlegen:"
|
|
echo ""
|
|
echo "Typ Partiton-UUID Label Size" | awk '{ printf "| %-10s| %-40s| %-20s| %-5s|\n", $1, $2, $3, $4 }'
|
|
awk 'BEGIN { for(f=1; f<= 84; f++) { if( f==1 || f==13 || f==55 || f==77 || f==84) { printf "|" } else { printf "-" } } printf "\n" }'
|
|
until [[ "${ANALYSE_STRING}" == "" ]]
|
|
do
|
|
local CURRENT_RESULT=$(echo "${ANALYSE_STRING}" | awk '{ print $1}')
|
|
local CURRENT_TYPE=$(echo "${CURRENT_RESULT}" | awk 'BEGIN { FS="=" } { print $1 }')
|
|
local CURRENT_UUID=$(echo "${CURRENT_RESULT}" | awk 'BEGIN { FS="=" } { print $2 }')
|
|
if [[ "${CURRENT_UUID}" == "null" ]]
|
|
then
|
|
CURRENT_UUID="${GUIDS[${CURRENT_TYPE}]}"
|
|
case ${CURRENT_TYPE} in
|
|
"USR")
|
|
CURRENT_LABEL="${USR_LABEL}"
|
|
CURRENT_SIZE="${USR_SIZE}"
|
|
;;
|
|
"USRHASH")
|
|
CURRENT_LABEL="${USRHASH_LABEL}"
|
|
CURRENT_SIZE="${USRHASH_SIZE}"
|
|
;;
|
|
"ROOT")
|
|
CURRENT_LABEL="${ROOT_LABEL}"
|
|
CURRENT_SIZE="${ROOT_SIZE}"
|
|
;;
|
|
"SWAP")
|
|
CURRENT_LABEL="${SWAP_LABEL}"
|
|
CURRENT_SIZE="${SWAP_SIZE}"
|
|
;;
|
|
"ESP")
|
|
CURRENT_LABEL="${ESP_LABEL}"
|
|
CURRENT_SIZE="${ESP_SIZE}"
|
|
;;
|
|
*)
|
|
die 1 "Unbekannter Partitionstyp"
|
|
;;
|
|
esac
|
|
echo "${CURRENT_TYPE}=${CURRENT_UUID}=${CURRENT_LABEL}=${CURRENT_SIZE}" | awk 'BEGIN { FS="=" } { printf "| %-10s| %-40s| %-20s| %-5s|\n", $1, $2, $3, $4 }'
|
|
fi
|
|
local CURRENT_REST=${ANALYSE_STRING//${CURRENT_RESULT}}
|
|
ANALYSE_STRING="${CURRENT_REST# }"
|
|
done
|
|
echo ""
|
|
echo -e "z.B. mit dem Kommando:\n# gdisk -n 0:0:+<SIZE> -t 0:<UUID> -c 0:<LABEL> ${DEVICE}\nDer Typ wird zum erstellen der Partition(en) nicht benötigt, da er durch die UUID bestimmt wird."
|
|
}
|
|
|
|
# format <Gerät>
|
|
format () {
|
|
local DEVICE="$1"
|
|
if [[ "${FORCE}" == "yes" ]]
|
|
then
|
|
erase "${DEVICE}"
|
|
fi
|
|
|
|
EXISTING_PARTITIONS=$(existing_partitions "${DEVICE}")
|
|
if [[ "${EXISTING_PARTITIONS}" == "no" ]]
|
|
then
|
|
create "TABLE" "${DEVICE}"
|
|
create "ESP" "${DEVICE}"
|
|
create "USR" "${DEVICE}"
|
|
create "ROOT" "${DEVICE}"
|
|
create "USRHASH" "${DEVICE}"
|
|
create "SWAP" "${DEVICE}"
|
|
else
|
|
read -r -p "Partitionen überschreiben? [N/y]: " ask_overwrite
|
|
ask_overwrite=${ask_overwrite:="n"}
|
|
if [[ ${ask_overwrite} == [Nn] ]]
|
|
then
|
|
#die 10 "Noch nicht implementiert"
|
|
ANALYSE_RESULT=$(partitions_analyse "${DEVICE}")
|
|
if [[ "${ANALYSE_RESULT}" =~ "null"+ ]]
|
|
then
|
|
echo "Irgendeine Partition fehlt"
|
|
echo ""
|
|
print "${ANALYSE_RESULT}"
|
|
print_todo "${DEVICE}" "${ANALYSE_RESULT}"
|
|
else
|
|
echo "Alle Partitionen gefunden, fahre fort mit den Script"
|
|
fi
|
|
else
|
|
erase "${DEVICE}"
|
|
create "TABLE" "${DEVICE}"
|
|
create "ESP" "${DEVICE}"
|
|
create "USR" "${DEVICE}"
|
|
create "ROOT" "${DEVICE}"
|
|
create "USRHASH" "${DEVICE}"
|
|
create "SWAP" "${DEVICE}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
### Start ###
|
|
|
|
# Optionen auslesen
|
|
while getopts :hfd:v:n:r:s:u: opt
|
|
do
|
|
case $opt in
|
|
h)
|
|
help
|
|
;;
|
|
f)
|
|
FORCE="yes"
|
|
;;
|
|
d)
|
|
DEVICE="$OPTARG"
|
|
;;
|
|
v)
|
|
VERSION=$OPTARG
|
|
;;
|
|
n)
|
|
NAME=$OPTARG
|
|
;;
|
|
r)
|
|
ROOT_SIZE=$OPTARG
|
|
;;
|
|
s)
|
|
SWAP_SIZE=$OPTARG
|
|
;;
|
|
u)
|
|
USR_SIZE=$OPTARG
|
|
;;
|
|
:)
|
|
die 2 '%s: Option benötigt ein Argument -- '\''%s'\' "${0##*/}" "$OPTARG"
|
|
;;
|
|
?)
|
|
die 2 '%s: Ungültige Option -- '\''%s'\' "${0##*/}" "$OPTARG"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
DEVICE=${DEVICE:="${DEFAULT_DEVICE}"}
|
|
FORCE=${FORCE:="no"}
|
|
NAME=${NAME:="${DEFAULT_NAME}"}
|
|
VERSION=${VERSION:="${DEFAULT_VERSION}"}
|
|
ESP_SIZE="${DEFAULT_ESP_SIZE}"
|
|
ESP_LABEL="${DEFAULT_ESP_LABEL}"
|
|
SWAP_SIZE=${SWAP_SIZE:="${DEFAULT_SWAP_SIZE}"}
|
|
SWAP_LABEL="${NAME} Swap"
|
|
ROOT_SIZE=${ROOT_SIZE:="${DEFAULT_ROOT_SIZE}"}
|
|
ROOT_LABEL="${NAME} Root"
|
|
USR_SIZE=${USR_SIZE:="${DEFAULT_USR_SIZE}"}
|
|
USR_LABEL="${NAME}_${VERSION}"
|
|
USRHASH_SIZE=${USRHASH_SIZE:="${DEFAULT_USRHASH_SIZE}"}
|
|
USRHASH_LABEL="${NAME}_${VERSION}"
|
|
|
|
#--------------------------------------#
|
|
|
|
|
|
|
|
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
|
|
|
|
echo "### DEBUG ###"
|
|
echo "DEVICE: ${DEVICE}"
|
|
echo "FORCE: ${FORCE}"
|
|
echo "NAME: ${NAME}"
|
|
echo "VERSION: ${VERSION}"
|
|
echo "ESP_SIZE: ${ESP_SIZE}"
|
|
echo "ESP_LABEL: ${ESP_LABEL}"
|
|
echo "USR_SIZE: ${USR_SIZE}"
|
|
echo "USR_LABEL: ${USR_LABEL}"
|
|
echo "USRHASH_SIZE: ${USRHASH_SIZE}"
|
|
echo "USRHASH_LABEL: ${USRHASH_LABEL}"
|
|
echo "ROOT_SIZE: ${ROOT_SIZE}"
|
|
echo "ROOT_LABEL: ${ROOT_LABEL}"
|
|
echo "SWAP_SIZE: ${SWAP_SIZE}"
|
|
echo "SWAP_LABEL: ${SWAP_LABEL}"
|
|
echo "### DEBUG ###"
|
|
|
|
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
|
|
|
|
|
|
|
|
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
|
|
|
|
# Prüfen, ob DEVICE existiert
|
|
|
|
#CHECK_PARTITION_EXISTENCE_OUTPUT=$(lsblk -pldo NAME | grep -ic "${DEVICE}")
|
|
|
|
#if ! lsblk -d "${DEVICE}" > /dev/null 2>&1 ; then
|
|
if [ ! -b "${DEVICE}" ]; then
|
|
die 3 "Gerät existiert nicht, Abbruch!"
|
|
fi
|
|
|
|
# Prüfen, ob das Script mit Root-Rechten ausgeführt wird
|
|
#(( EUID == 0)) || die 3 "Dieses Script muss mit Root-Privilegien aufgerufen werden"
|
|
|
|
format "${DEVICE}" |