Merge full_rewrite branch

This commit is contained in:
Yorick Barbanneau 2020-02-12 17:32:28 +01:00
commit 9c4931058c
5 changed files with 307 additions and 178 deletions

7
.gitignore vendored
View file

@ -1,7 +1,2 @@
tmp/ tmp/
syslinux/*.c32 repo/
syslinux/ldlinux.*
EFI
debian-8.5.0-amd64-netinst.iso
vmlinuz
initrd.gz

View file

@ -1,44 +1,64 @@
Debian Auto Installer Debian Auto Installer
==================== =====================
A set of tools to create automated Debian Installation Key. I created this tools A script to create automated Debian Installation Key. I created it for my work.
for my work. You can create bios, efi64 key but prepare file in the folder You can create bios, efi64 key or prepare files into a folder whitout creating
whitout creating key. key.
* init.sh : script to create USB key * init.sh : script to create USB key
* preseed : textfile that contain all instructions for Debian Installer * preseeds : folder containing all preseeds files
* partman : partition recipe for preseed * partman_recipes : folder containinf partman recipes
* syslinux/syslinux.cfg : Syslinux configuration file * syslinux/syslinux.cfg : Syslinux configuration file
* conf/*.conf : "folder configuration" files
# Howto create usb key
1. Plug your key
2. Make sure yout key is not mounted
3. Execute ``./init.sh -d /dev/sdb`` (replace /dev/sdb with your device)
4. Done!
# Init.sh command line options # Init.sh command line options
* ``-a [amd64|i386]`` choose architecture for debian files (default amd64) * ``-a [amd64|i386]`` choose architecture for debian files (default amd64)
* ``-b`` create key for bios boot architecture (default efi64) * ``-b`` create key for bios boot architecture (default efi64)
* ``-c --conf`` set folder configuration files (default conf/archlinux.conf)
* ``-d device`` USB device like /dev/sdb * ``-d device`` USB device like /dev/sdb
* ``--debian-version`` debian iso version to download (default lastest stable)
* ``--repo`` repository folder (default ./repo)
* ``--tmp`` Temporary folder used to create USB key to create directory tree
Be careful : if ``-d`` parameter is define then the relative peripheral will Be careful : if ``-d`` parameter is define then the usb key / external drive
be erased will be erased.
For now, this script doesn't verify the state of your device (is mounted or not) Since syslinux files are placed differently depending on the distribution,
but this is planned. configuration file (``-c``) contain directory to syslinux files :
## Exemples * __syslinux_mbr_bl_folder__ : folder containing mbr.bin
* __syslinux_efi_bl_folder__ : folder containing efi64 folder
* __syslinux_modules_folder__ : folder containing syslinux modules folders
Prepare file in directory for efi system without writing an usb key for AMD64 arch. ## Examples
Prepare file in directory for efi system without writing an usb key for AMD64.
``` ```
./init.sh ./init.sh
``` ```
Prepare an usb key (/dev/sdb) for bios / i386 architecture Prepare an USB key (/dev/sdb) for bios / i386 architecture
``` ```
./init.sh -a i386 -b -d /dev/sdb ./init.sh -a i386 -b -d /dev/sdb
``` ```
Prepare an USB key on Debian
```
./init.sh -d /dev/sdb -c conf/debian.conf
```
# How it work
1. Create a repo folder then a subfolder named with debian version then
download debian iso, vmlinuz and initrt.gz.
2. Create a temporary folder and copy all necessary files into it (pressed,
partman recipes, syslinux modules...).
4. If ``-d /dev/sdx``, unmount usb key( if mounted) and create partition scheme,
format and mount partitions.
5. Copy all content of temporary folder into mounted usb key.
6. Unmount usb key.

4
conf/archlinux.conf Normal file
View file

@ -0,0 +1,4 @@
# Archlinux syslinux folder configuration
syslinux_mbr_bl_folder="/usr/lib/syslinux/bios"
syslinux_efi_bl_folder="/usr/lib/syslinux"
syslinux_modules_folder="/usr/lib/syslinux"

4
conf/debian.conf Normal file
View file

@ -0,0 +1,4 @@
# Debian syslinux folder configuration
syslinux_mbr_bl_folder="/usr/lib/SYSLINUX"
syslinux_efi_bl_folder="/usr/lib/SYSLINUX.EFI"
syslinux_modules_folder="/usr/lib/syslinux"

404
init.sh
View file

@ -6,225 +6,331 @@
# Dépend : syslinux,wget # Dépend : syslinux,wget
# #
OPTIND=1 OPTIND=1
DEBIAN_VERSION="9.2.0"
DEBIAN_ARCH="amd64" # Default Variables
BOOT_TYPE="efi64" debian_arch="amd64"
SYSLINUX_EXE=`which syslinux` 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=$(which syslinux)
PARTED_EXE=$(which parted)
SYSLINUX_FILES="menu.c32 vesamenu.c32 libutil.c32 libcom32.c32" SYSLINUX_FILES="menu.c32 vesamenu.c32 libutil.c32 libcom32.c32"
SYSLINUX_BIOS_FILES="" SYSLINUX_BIOS_FILES=""
SYSLINUX_EFI_FILES="ldlinux.e64" SYSLINUX_EFI_FILES="ldlinux.e64"
TMP_DIR="tmp"
REPO_DIR="repo" process_args() {
MOUNT_DIR="/mnt/usbstick" # While getops doesn't handle long parameters
current_dir=`pwd` # 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() { usage() {
cat << EOF cat << EOF
USAGE: ${0} [-a architecture] [-b] USAGE: ${0} [-a architecture] [-b]
-a amd64 | i386 CPU architecture -a | --arch Select CPU Architecture amd64 | i386 CPU
-b bios boot type (default is efi64) -b | --bios Create a bios bott compatible key
-d device_block USB key to write -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. ${0} initialize an usb key for Debian automatic install with preseed and a partman recipe.
EOF EOF
} }
show_version () {
printf "%s %s 2016-2017 ephase@xieme-art.org\n" "$APP_NAME" "$VERSION"
}
download (){ download (){
#Download function #Download function
# $1 : filename # $1 : filename
# $2 : url # $2 : url
# $3 : 1 if abort download if file exist # $3 : 1 if abort download if file exist
echo -ne "Downloading $1 ... " printf "Downloading %s : " "$1"
if [[ -f $1 && $3 == "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 then
echo file already downloaded. printf " \b\b\b\b\b done\n "
return else
printf " error, exiting.\n"
exit 1
fi fi
wget no-clobber -4 $2/$1 &> /dev/null else
echo "done!" 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(){ create_dir(){
# $1 directory to create # $1 directory to create
if [ ! -d $1 ] if [ ! -d "$1" ]
then then
mkdir -p $1 mkdir -p "$1"
else else
if [[ $2 == 1 ]] if [ -n "$2" ] && [ "$2" -eq 1 ]
then then
rm -rf $1 rm -rf "$1"
create_dir $1 create_dir "$1"
fi fi
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 #Stop script if syslinux is not installed
if [[ $SYSLINUX_EXE == "" ]] if [ -z "$SYSLINUX_EXE" ]
then then
echo "Syslinux not found, script can't continue…" printf "Syslinux not found, script can't continue.\n"
exit 1 exit 1
fi fi
if [ -d /usr/lib/syslinux/efi64 ] if [ -z "$PARTED_EXE" ]
then then
syslinux_mod="/usr/lib/syslinux" printf "Parted not found, script can't continue.\n"
else exit 1
if [ -d /usr/lib/syslinux/modules/efi64 ]
then
syslinux_mod="/usr/lib/syslinux/modules"
else
echo "Syslinux modules folder not found, exiting"
exit 1
fi
fi fi
# Arguments ... process_args "$@"
while getopts "ha:bd:" opt; do process_conf_file "$conf_file"
case "$opt" in if [[ ! -d "$syslinux_mbr_bl_folder" || ! -d "$syslinux_efi_bl_folder" || ! -d "$syslinux_modules_folder" ]]
h) then
usage printf "Bad folder configuration in %s\n" "$conf_file"
exit 0 exit 1
;; fi
a)
if [[ $OPTARG == "amd64" || $OPTARG == "i386" ]]
then
DEBIAN_ARCH=$OPTARG
else
echo "CPU architecture must be amd64 of i386, bye."
exit 1
fi
;;
b)
BOOT_TYPE="bios"
;;
d)
if [ -b $OPTARG ]
then
dest=$OPTARG
else
echo "Destination is not a block device, bye."
exit 1
fi
;;
esac
done
bootfiles_Debian="http://ftp.debian.org/debian/dists/jessie/main/installer-${DEBIAN_ARCH}/current/images/hd-media" bootfiles_Debian="http://ftp.debian.org/debian/dists/stable/main/installer-${debian_arch}/current/images/hd-media"
iso_url="http://cdimage.debian.org/debian-cd/${DEBIAN_VERSION}/${DEBIAN_ARCH}/iso-cd" if [ $archive -eq 1 ]
iso_file="debian-${DEBIAN_VERSION}-${DEBIAN_ARCH}-netinst.iso" then
repo_path="$REPO_DIR/$DEBIAN_ARCH/$DEBIAN_VERSION" 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) # Download Debian files (kernel, initrd and iso)
echo -e "\nPrepare Debian files\n---" printf "Downloading Debian files\n---\n"
# Création du répertoire temporaire # Création du répertoire temporaire
create_dir $repo_path create_dir "$repo_path"
cd $repo_path cd "$repo_path"
download $iso_file $iso_url 1
download "$iso_file" "$iso_url" 1
for file in "vmlinuz" "initrd.gz" for file in "vmlinuz" "initrd.gz"
do do
download $file $bootfiles_Debian 1 download "$file" "$bootfiles_Debian" 1
done done
cd $current_dir cd "$current_dir"
if [[ -z $dest ]] if [ -z "$device" ]
then then
echo "No destination device specified, USB key will not be created." printf "No destination device specified, USB key will not be created.\n"
fi fi
create_dir $TMP_DIR 1 create_dir "$tmp_dir" 1
cp $repo_path/$iso_file $TMP_DIR cp "$repo_path/$iso_file" "$tmp_dir"
# Copy wanted syslinux file from archive # Copy wanted syslinux file from archive
case $BOOT_TYPE in case $boot_type in
efi64) efi64)
if [ -f /usr/lib/syslinux/efi64/syslinux.efi ] syslinux_folder=${tmp_dir}/efi/EFI/boot
then create_dir "$syslinux_folder"
syslinux_efi="/usr/lib/syslinux/efi64/syslinux.efi" cp -T "$syslinux_efi_bl_folder/$boot_type/syslinux.efi" "$syslinux_folder/bootx64.efi" &> /dev/null
else
if [ -d /usr/lib/SYSLINUX.EFI/modules/efi64/syslinux.efi ]
then
syslinux_efi="/usr/lib/SYSLINUX.EFI/efi64/syslinux.efi"
else
echo "Syslinux efi bootlader not found"
exit 1
fi
fi
syslinux_folder=${TMP_DIR}/efi/EFI/boot
create_dir $syslinux_folder
cp -T ${syslinux_efi} $syslinux_folder/bootx64.efi &> /dev/null
for file in $SYSLINUX_EFI_FILES for file in $SYSLINUX_EFI_FILES
do do
echo "copying $file ..." printf "copying %s \n" "$file"
cp $syslinux_mod/$BOOT_TYPE/$file $syslinux_folder cp "$syslinux_modules_folder/$boot_type/$file" "$syslinux_folder"
done done
for file in $SYSLINUX_FILES cp "$repo_path"/{vmlinuz,initrd.gz} "$tmp_dir/efi"
do cp -R syslinux/syslinux.cfg "$syslinux_folder" &> /dev/null
echo "copie de $file"
cp ${syslinux_mod}/${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) bios)
create_dir ${TMP_DIR}/syslinux 1 syslinux_folder=${tmp_dir}/syslinux
for file in $SYSLINUX_FILES create_dir "$syslinux_folder"
do
echo "copie de $file"
cp ${syslinux_mod}/${BOOT_TYPE}/${file} ${TMP_DIR}/syslinux/
done
for file in $SYSLINUX_BIOS_FILES for file in $SYSLINUX_BIOS_FILES
do do
echo "copying $file ..." printf "copying %s\n" "$file"
cp ${syslinux_mod}/${BOOT_TYPE}/${file} ${TMP_DIR}/syslinux/ cp "$syslinux_modules_folder/$boot_type/$file" "$syslinux_folder"
done done
cp -R syslinux $TMP_DIR &> /dev/null cp "$repo_path"/{vmlinuz,initrd.gz} "$tmp_dir"
cp -R syslinux "$tmp_dir" &> /dev/null
;; ;;
esac esac
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 $dest ]] 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 then
read -p "[WARNING] Disk $dest will be erased continue [Y/N]? " -n 1 -r printf "Partitionning and formating %s\n" "$device"
read -p "[WARNING] Disk $device will be erased continue [Y/N]? " -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]] if [[ ! $REPLY =~ ^[Yy]$ ]]
then then
exit 1 exit 1
fi 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 #dd if=/dev/zero of=${dest} bs=512 count=1 conv=notrunc &> /dev/null
echo -e "\nCreating partition" case "$boot_type" in
parted -s $dest mklabel gpt mkpart EFS fat32 1MiB 128MiB set 1 boot on "efi64")
parted -s $dest mkpart EFS fat32 128MiB 100% efi_create_key_structure "$device" "$key_mountpoint"
mkfs.vfat ${dest}1 -n efi &> /dev/null ;;
mkfs.vfat ${dest}2 -n debian &> /dev/null "bios")
bios_create_key_structure "$device" "$key_mountpoint"
# mount and copy ;;
create_dir $MOUNT_DIR esac
mount ${dest}2 $MOUNT_DIR printf "copying all file to USB drive\n"
create_dir $MOUNT_DIR/efi cp -R "$tmp_dir"/* "$key_mountpoint"
mount ${dest}1 $MOUNT_DIR/efi umount_device "$device"
echo "copying all file to USB drive"
cp -R ${TMP_DIR}/* $MOUNT_DIR
umount $MOUNT_DIR/efi
umount $MOUNT_DIR
echo Unmounting key, please wait ...
sleep 5 sleep 5
# Make key bootable if bios. # Make key bootable if bios.
if [[ $BOOT_TYPE == "bios" ]] if [ "$boot_type" = "bios" ]
then then
# In this mode, we need to write syslinux MBR. # In this mode, we need to write syslinux MBR.
echo "Writing syslinux mbr.ini fo $dest" printf "Writing syslinux mbr.ini to %s\n" "$device"
dd bs=440 count=1 conv=notrunc if=${syslinux_mod}/${BOOT_TYPE}/mbr.bin of=${dest} dd bs=440 count=1 conv=notrunc if="$syslinux_mbr_bl_folder"/mbr.bin of="$device"
sleep 2 sleep 2
syslinux --directory /syslinux --install ${dest}1 "$SYSLINUX_EXE" --directory /syslinux --install "${device}1"
fi fi
rm -rf "$tmp_dir"
printf "\nBootable USB key created\n"
exit 0 exit 0
#rm -rf $TMP_DIR
fi fi