345 lines
9.1 KiB
Bash
Executable file
345 lines
9.1 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Script de creation d'un media bootable Debian
|
|
# Pour l'ACAQB
|
|
#
|
|
# Dépend : syslinux,wget
|
|
#
|
|
OPTIND=1
|
|
|
|
# Default Variables
|
|
debian_arch="amd64"
|
|
debian_version=$(wget -q --output-document - https://cdimage.debian.org/debian-cd/ | \
|
|
grep -o '[0-9]\{1,2\}\.[0-9]\{1,2\}\.[0.9]\{1,2\}' | head -1)
|
|
archive=0
|
|
boot_type="efi64"
|
|
repo_dir="repo"
|
|
tmp_dir="tmp"
|
|
current_dir=`pwd`
|
|
|
|
# In Archlinux, this is default files for syslinux...
|
|
conf_file="conf/archlinux.conf"
|
|
key_mountpoint="/mnt/usbstick"
|
|
device=""
|
|
|
|
# constant
|
|
APP_NAME="Debian USB Creator"
|
|
VERSION="1.99.0"
|
|
SYSLINUX_EXE=$(command -v syslinux)
|
|
PARTED_EXE=$(command -v parted)
|
|
MCOPY=$(command -v mcopy)
|
|
SYSLINUX_FILES="menu.c32 vesamenu.c32 libutil.c32 libcom32.c32"
|
|
SYSLINUX_BIOS_FILES=""
|
|
SYSLINUX_EFI_FILES="ldlinux.e64"
|
|
|
|
process_args() {
|
|
# While getops doesn't handle long parameters
|
|
# I need an personnal function
|
|
# Inspired by http://mywiki.wooledge.org/BashFAQ/035
|
|
while :; do
|
|
case $1 in
|
|
-h|-\?|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
-a|--arch)
|
|
if [[ $2 == "amd64" || $2 == "i386" ]]
|
|
then
|
|
debian_arch=$2
|
|
shift
|
|
else
|
|
printf "Error : CPU architecture must be amd64 or i386"
|
|
exit 1
|
|
fi
|
|
;;
|
|
-b|--bios)
|
|
boot_type="bios"
|
|
;;
|
|
-c|--conf)
|
|
if [ -f $2 ]
|
|
then
|
|
conf_file=$2
|
|
else
|
|
printf "%s file not found" $2
|
|
exit 1
|
|
fi
|
|
shift
|
|
;;
|
|
-d|--device)
|
|
if [ -b $2 ]
|
|
then
|
|
device=$2
|
|
shift
|
|
else
|
|
printf "%s doesn't a block device, exiting" "$2"
|
|
exit 1
|
|
fi
|
|
;;
|
|
--debian-version)
|
|
if [[ $debian_version != $2 ]]
|
|
then
|
|
archive=1
|
|
debian_version=$2
|
|
fi
|
|
shift
|
|
;;
|
|
--repo)
|
|
repo_dir=$2
|
|
shift
|
|
;;
|
|
--tmp)
|
|
tmp_dir=$2
|
|
shift
|
|
;;
|
|
-v|--version)
|
|
show_version
|
|
exit 0
|
|
;;
|
|
*)
|
|
break
|
|
esac
|
|
shift
|
|
done
|
|
}
|
|
|
|
usage() {
|
|
cat << EOF
|
|
USAGE: ${0} [-a architecture] [-b]
|
|
-a | --arch Select CPU Architecture amd64 | i386 CPU
|
|
-b | --bios Create a bios bott compatible key
|
|
-d | --device Device_block USB key to write
|
|
--debian-version Choose Debian Version to download
|
|
--repo Repo directory (defaukt is ./repo)
|
|
--temp Temp directory (default is ./tmp)
|
|
-v | --version Show version
|
|
|
|
${0} initialize an usb key for Debian automatic install with preseed and a partman recipe.
|
|
EOF
|
|
}
|
|
|
|
show_version () {
|
|
printf "%s %s 2016-2017 ephase@xieme-art.org\n" "$APP_NAME" "$VERSION"
|
|
}
|
|
|
|
download (){
|
|
#Download function
|
|
# $1 : filename
|
|
# $2 : url
|
|
# $3 : 1 if abort download if file exist
|
|
printf "Downloading %s : " "$1"
|
|
local url
|
|
local http_response
|
|
url="$2/$1"
|
|
http_response=$(wget --spider --server-response "$url" 2>&1 | grep HTTP/ | tail -1 | awk ' { printf $2 }')
|
|
if [ "$http_response" -eq 200 ]
|
|
then
|
|
wget -c --progress=dot "$url" 2>&1 | grep --line-buffered "[0-9]\{1,3\}%" -o | awk '{printf ("\b\b\b\b%4s", $1)}'
|
|
if [ $? -eq 0 ]
|
|
then
|
|
printf " \b\b\b\b\b done\n "
|
|
else
|
|
printf " error, exiting.\n"
|
|
exit 1
|
|
fi
|
|
else
|
|
printf "Error 404 : file not found, exiting\n"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
process_conf_file (){
|
|
while read -r p
|
|
do
|
|
var=$(echo "$p" | awk -F"=" '{print $1}')
|
|
param=$(echo "$p" | awk -F"=" '{print $2}')
|
|
eval "$var"="$param"
|
|
done < <( cat "$1" | grep '^[^#].*')
|
|
|
|
}
|
|
|
|
create_dir(){
|
|
# $1 directory to create
|
|
if [ ! -d "$1" ]
|
|
then
|
|
mkdir -p "$1"
|
|
else
|
|
if [ -n "$2" ] && [ "$2" -eq 1 ]
|
|
then
|
|
rm -rf "$1"
|
|
create_dir "$1"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# unmount if device is mounted
|
|
umount_device (){
|
|
local mounted_part=""
|
|
mounted_part=$(mount | grep "${1}[0-9]" | awk '{print $3}')
|
|
if [ ! "$mounted_part" == "" ]
|
|
then
|
|
for part in $mounted_part
|
|
do
|
|
if [ -d "$part" ]
|
|
then
|
|
printf "Unmount %s\n " "$part"
|
|
umount "$part" --recursive
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
efi_create_key_structure () {
|
|
parted -s "$1" mklabel gpt mkpart EFS fat32 1MiB 128MiB set 1 boot on mkpart debian fat32 128MiB 100%
|
|
sleep 2
|
|
mkfs.vfat "${1}1" -n efi &> /dev/null
|
|
mkfs.vfat "${1}2" -n debian &> /dev/null
|
|
sync
|
|
mount "${1}2" "$2"
|
|
create_dir "$2/efi"
|
|
mount "${1}1" "$2/efi"
|
|
}
|
|
|
|
bios_create_key_structure() {
|
|
parted -s "$1" mklabel msdos mkpart primary fat32 1MiB 100% set 1 boot on
|
|
sleep 2
|
|
mkfs.vfat "${1}1" -n debian &> /dev/null
|
|
mount "${1}1" "$2"
|
|
}
|
|
|
|
#Stop script if syslinux is not installed
|
|
if [ -z "$SYSLINUX_EXE" ]
|
|
then
|
|
printf "Syslinux not found, script can't continue.\n"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$PARTED_EXE" ]
|
|
then
|
|
printf "Parted not found, script can't continue.\n"
|
|
exit 1
|
|
fi
|
|
|
|
|
|
process_args "$@"
|
|
process_conf_file "$conf_file"
|
|
if [[ ! -d "$syslinux_mbr_bl_folder" || ! -d "$syslinux_efi_bl_folder" || ! -d "$syslinux_modules_folder" ]]
|
|
then
|
|
printf "Bad folder configuration in %s\n" "$conf_file"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$boot_type" == "bios" ] && [ -z "$MCOPY" ]
|
|
then
|
|
printf "Bios key creation need mcopy from mtools packages\n"
|
|
exit 1
|
|
fi
|
|
|
|
bootfiles_Debian="http://ftp.debian.org/debian/dists/stable/main/installer-${debian_arch}/current/images/hd-media"
|
|
if [ $archive -eq 1 ]
|
|
then
|
|
iso_url="http://cdimage.debian.org/cdimage/archive/${debian_version}/${debian_arch}/iso-cd"
|
|
else
|
|
iso_url="http://cdimage.debian.org/debian-cd/${debian_version}/${debian_arch}/iso-cd"
|
|
fi
|
|
iso_file="debian-${debian_version}-${debian_arch}-netinst.iso"
|
|
repo_path="$repo_dir/$debian_arch/$debian_version"
|
|
|
|
|
|
# Download Debian files (kernel, initrd and iso)
|
|
printf "Downloading Debian files\n---\n"
|
|
|
|
# Création du répertoire temporaire
|
|
create_dir "$repo_path"
|
|
cd "$repo_path"
|
|
|
|
download "$iso_file" "$iso_url" 1
|
|
for file in "vmlinuz" "initrd.gz"
|
|
do
|
|
download "$file" "$bootfiles_Debian" 1
|
|
done
|
|
cd "$current_dir"
|
|
|
|
if [ -z "$device" ]
|
|
then
|
|
printf "No destination device specified, USB key will not be created.\n"
|
|
fi
|
|
create_dir "$tmp_dir" 1
|
|
cp "$repo_path/$iso_file" "$tmp_dir"
|
|
# Copy wanted syslinux file from archive
|
|
|
|
case $boot_type in
|
|
efi64)
|
|
syslinux_folder=${tmp_dir}/efi/EFI/boot
|
|
create_dir "$syslinux_folder"
|
|
cp -T "$syslinux_efi_bl_folder/$boot_type/syslinux.efi" "$syslinux_folder/bootx64.efi" &> /dev/null
|
|
for file in $SYSLINUX_EFI_FILES
|
|
do
|
|
printf "copying %s \n" "$file"
|
|
cp "$syslinux_modules_folder/$boot_type/$file" "$syslinux_folder"
|
|
done
|
|
cp "$repo_path"/{vmlinuz,initrd.gz} "$tmp_dir/efi"
|
|
cp -R syslinux/syslinux.cfg "$syslinux_folder" &> /dev/null
|
|
|
|
;;
|
|
bios)
|
|
syslinux_folder=${tmp_dir}/syslinux
|
|
create_dir "$syslinux_folder"
|
|
for file in $SYSLINUX_BIOS_FILES
|
|
do
|
|
printf "copying %s\n" "$file"
|
|
cp "$syslinux_modules_folder/$boot_type/$file" "$syslinux_folder"
|
|
done
|
|
cp "$repo_path"/{vmlinuz,initrd.gz} "$tmp_dir"
|
|
cp -R syslinux "$tmp_dir" &> /dev/null
|
|
;;
|
|
esac
|
|
|
|
for file in $SYSLINUX_FILES
|
|
do
|
|
printf "copying %s\n" "$file"
|
|
cp "$syslinux_modules_folder/$boot_type/$file" "$syslinux_folder"
|
|
done
|
|
|
|
echo Copying configurations files
|
|
create_dir "$tmp_dir/partman_recipes"
|
|
cp -R partman_recipes "$tmp_dir" &> /dev/null
|
|
create_dir "$tmp_dir/preseeds"
|
|
cp -R preseeds "$tmp_dir" &> /dev/null
|
|
|
|
if [ -n "$device" ]
|
|
then
|
|
printf "Partitionning and formating %s\n" "$device"
|
|
read -p "[WARNING] Disk $device will be erased continue [Y/N]? " -n 1 -r
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
|
then
|
|
exit 1
|
|
fi
|
|
printf "\n\n"
|
|
umount_device "$device"
|
|
create_dir "$key_mountpoint"
|
|
#dd if=/dev/zero of=${dest} bs=512 count=1 conv=notrunc &> /dev/null
|
|
case "$boot_type" in
|
|
"efi64")
|
|
efi_create_key_structure "$device" "$key_mountpoint"
|
|
;;
|
|
"bios")
|
|
bios_create_key_structure "$device" "$key_mountpoint"
|
|
;;
|
|
esac
|
|
printf "copying all file to USB drive\n"
|
|
cp -R "$tmp_dir"/* "$key_mountpoint"
|
|
umount_device "$device"
|
|
sleep 5
|
|
# Make key bootable if bios.
|
|
if [ "$boot_type" = "bios" ]
|
|
then
|
|
# In this mode, we need to write syslinux MBR.
|
|
printf "Writing syslinux mbr.ini to %s\n" "$device"
|
|
dd bs=440 count=1 conv=notrunc if="$syslinux_mbr_bl_folder"/mbr.bin of="$device"
|
|
sleep 2
|
|
"$SYSLINUX_EXE" --directory /syslinux --install "${device}1"
|
|
fi
|
|
rm -rf "$tmp_dir"
|
|
printf "\nBootable USB key created\n"
|
|
exit 0
|
|
fi
|