diff options
Diffstat (limited to 'backend')
-rwxr-xr-x | backend/backend.sh.in | 96 | ||||
-rw-r--r-- | backend/modules/bootloader | 158 | ||||
-rw-r--r-- | backend/modules/cleanup | 15 | ||||
-rw-r--r-- | backend/modules/common | 13 | ||||
-rw-r--r-- | backend/modules/config | 68 | ||||
-rw-r--r-- | backend/modules/frontend | 21 | ||||
-rw-r--r-- | backend/modules/hdmap | 340 | ||||
-rw-r--r-- | backend/modules/init | 11 | ||||
-rw-r--r-- | backend/modules/install | 75 | ||||
-rw-r--r-- | backend/modules/install_configure | 152 | ||||
-rw-r--r-- | backend/modules/install_main | 302 | ||||
-rw-r--r-- | backend/modules/install_services | 19 | ||||
-rw-r--r-- | backend/modules/partitions | 251 | ||||
-rw-r--r-- | backend/modules/partmgr | 24 |
14 files changed, 1545 insertions, 0 deletions
diff --git a/backend/backend.sh.in b/backend/backend.sh.in new file mode 100755 index 0000000..4c0c161 --- /dev/null +++ b/backend/backend.sh.in @@ -0,0 +1,96 @@ +#!/bin/bash + +cd "$(dirname "$0")" +SEARCHPATH="@DATA_INSTALL_DIR@" +[ ! -e "$SEARCHPATH" -a -e ./modules ] && SEARCHPATH="." + +for i in $(find $SEARCHPATH/modules/ -type f | sort); do + source $i +done + +function print_usage() +{ +cat <<EOF >&2 +$(basename $0): + + -ni + NonInteractive mode, no prompt is shown and INSTALLER_OUTPUT is set to 1 + -e command + Run "command" + +EOF +exit 0 +} + +function set_debug() +{ + case $1 in + on) + PS4="<acritoxinstaller debug> " + set -x + ;; + off) + set +x + PS4="+" + ;; + esac +} + +if ((UID)); then + p="$PWD/$(basename "$0")" + if [ -x /usr/bin/sudo ]; then + if /usr/bin/sudo -n -l "$p" &>/dev/null; then + /usr/bin/sudo "$p" "$@" + exit $? + fi + fi + if [ -x /usr/lib/kde4/libexec/kdesu ]; then + /usr/lib/kde4/libexec/kdesu --noignorebutton -d -- "$p" --pid $$ "$@" &>/dev/null + exit $? + fi + if [ -z "$as_root" ]; then + for as_root in /usr/bin/kdesu /usr/bin/gksu exec + do + [ -x $as_root ] && break + done + fi + $as_root "$p" --pid $$ "$@" &>/dev/null + exit $? +fi + +while [ "$1" ] +do + case $1 in + "-ni") + export INSTALLER_OUTPUT=1 + ;; + "-e") + shift + eval "$@" + exit $? + ;; + "--pid") + exec 0<"/proc/$2/fd/0" 1>"/proc/$2/fd/1" 2>"/proc/$2/fd/2" + shift + ;; + "-h") + print_usage + ;; + esac + shift +done + +EOT="$(echo -e '\004')" +while true +do + if ((INSTALLER_OUTPUT)); then + echo "<acritoxinstaller prompt>" + IFS=" " read -d "$EOT" -r command params + else + IFS=" " read -er -p "installer> " command params + fi + declare -F ${command}_pre &>/dev/null && eval "${command}_pre" + eval "$command $params" + declare -F ${command}_post &>/dev/null && eval "${command}_post" +done + diff --git a/backend/modules/bootloader b/backend/modules/bootloader new file mode 100644 index 0000000..a3f7546 --- /dev/null +++ b/backend/modules/bootloader @@ -0,0 +1,158 @@ +#!/bin/bash + +# Synopsis: list_bootloader_targets +# +# This function lists all disks and the root-partition if it is suitable to install a bootloader on it. +# Output example: +# /dev/sda:MBR:250059350016 +# /dev/sdb:MBR:400088457216 +# /dev/sdb1:Rootpartition:60003385344 +function list_bootloader_targets() +{ + for disk in $(list_all_disks) + do + echo "$disk - MBR $(blockdev --getsize64 $disk)" + done + root_dev="$(hdmap_get device of mountpoint /)" + root_fs="$(hdmap_get filesystem of mountpoint /)" + [ -z "$root_fs" ] && root_fs=$(get_filesystem "$root_dev") + case $root_fs in + reiserfs|ext2|ext3|ext4) + list_linux_partitions | grep -q "^$root_dev$" && + echo "$root_dev - Rootpartition $(blockdev --getsize64 $root_dev)" + ;; + esac +} + +function send_bootloader_targets() +{ + send data bootloader_targets + list_bootloader_targets +} + +# Synopsis: list_bootloaders +# +# This function lists all available bootloaders +# Output example: +# BURG - Brand-new Universal loadeR from GRUB +# GRUB - GRand Unified Bootloader +function list_bootloaders() +{ + for bl in burg grub + do + [ -x /usr/sbin/$bl-setup ] || continue + case $bl in + burg) echo "BURG - Brand-new Universal loadeR from GRUB";; + grub) echo "GRUB - GRand Unified Bootloader";; + esac + done +} + +function send_bootloaders() +{ + send data bootloaders + list_bootloaders +} + +function install_bootmanager_to_target() +{ + send install_step install_bootmanager_to_target + # force initrd update + [ -d $TARGET/var/lib/initramfs-tools ] && rm -f $TARGET/var/lib/initramfs-tools/* + chroot_it update-initramfs -utk all &>/dev/null + + case "$cfg_bootloader" in + grub) + install_grub + ;; + burg) + install_burg + ;; + esac +} + +function install_grub() +{ + rm -f $TARGET/boot/vmlinuz $TARGET/boot/System.map $TARGET/boot/initrd.img + + # install grub + mkdir -p "$TARGET/boot/grub" + grub-install --recheck --no-floppy --root-directory=$TARGET "$cfg_bootloader_target" &>/dev/null || \ + grub-install --force --recheck --no-floppy --root-directory=$TARGET "$cfg_bootloader_target" &>/dev/null + +# # create device.map and save it to target +# export device_map=$TARGET/tmp/device.map +# get_device_map > $device_map +# cat $device_map > $TARGET/boot/grub/device.map +# rm -f $device_map + + # preseed grub-pc with install-target + for path in /dev/disk/by-id/* + do + [ -e "$path" ] || continue + if [ "$(readlink -f "$path")" = "$(readlink -f "$cfg_bootloader_target")" ]; then + echo "grub-pc grub-pc/install_devices multiselect $path" | chroot_it debconf-set-selections &>/dev/null + break + fi + done + + write_kernel_img_conf + + # update grub + chroot_it update-grub &>/dev/null + DEBIAN_FRONTEND=noninteractive chroot_it dpkg-reconfigure grub-pc &>/dev/null + + return 0 +} + +function install_burg() +{ + rm -f $TARGET/boot/vmlinuz $TARGET/boot/System.map $TARGET/boot/initrd.img + + # install burg + mkdir -p "$TARGET/boot/burg" + burg-install --recheck --no-floppy --root-directory=$TARGET "$cfg_bootloader_target" &>/dev/null || \ + burg-install --force --recheck --no-floppy --root-directory=$TARGET "$cfg_bootloader_target" &>/dev/null + +# # create device.map and save it to target +# export device_map=$TARGET/tmp/device.map +# get_device_map > $device_map +# cat $device_map > $TARGET/boot/burg/device.map +# rm -f $device_map + + # preseed burg-pc with install-target + for path in /dev/disk/by-id/* + do + [ -e "$path" ] || continue + if [ "$(readlink -f "$path")" = "$(readlink -f "$cfg_bootloader_target")" ]; then + echo "burg-pc burg-pc/install_devices multiselect $path" | chroot_it debconf-set-selections &>/dev/null + break + fi + done + + write_kernel_img_conf + + # update burg + chroot_it update-burg &>/dev/null + DEBIAN_FRONTEND=noninteractive chroot_it dpkg-reconfigure burg-pc &>/dev/null + + return 0 +} + +function write_kernel_img_conf() +{ +rm -f $TARGET/etc/kernel-img.conf +cat << EOT > $TARGET/etc/kernel-img.conf +# Kernel image management overrides +# See kernel-img.conf(5) for details +do_symlinks = yes +relative_links = yes +do_bootloader = no +do_bootfloppy = no +do_initrd = yes +link_in_boot = no +postinst_hook = update-$cfg_bootloader +postrm_hook = update-$cfg_bootloader +EOT +} + diff --git a/backend/modules/cleanup b/backend/modules/cleanup new file mode 100644 index 0000000..fe604a0 --- /dev/null +++ b/backend/modules/cleanup @@ -0,0 +1,15 @@ +#!/bin/bash + +function cleanup() +{ + + cd / + umount "$TARGET/proc" &>/dev/null + umount "$TARGET/dev" &>/dev/null + umount "$TARGET/sys" &>/dev/null + umount_all_affected "$(hdmap_get device of mountpoint /)" &>/dev/null + umount "$TARGET" &>/dev/null + umount "/live/filesystem" &>/dev/null + rmdir "$TARGET" "/live/filesystem" &>/dev/null +} + diff --git a/backend/modules/common b/backend/modules/common new file mode 100644 index 0000000..5c763f3 --- /dev/null +++ b/backend/modules/common @@ -0,0 +1,13 @@ +#!/bin/bash + +# Synopsis: dereferce_links_in_list +# +# This function reads a list from STDIN, dereferences the links and prints it to STDOUT +function dereferce_links_in_list() +{ + for lnk in $(cat) + do + readlink -m $lnk + done +} + diff --git a/backend/modules/config b/backend/modules/config new file mode 100644 index 0000000..d073580 --- /dev/null +++ b/backend/modules/config @@ -0,0 +1,68 @@ +#!/bin/bash + +declare -A cfg flags + +function cfg_get() +{ + while [ "$1" ]; + do + send data value + echo "${cfg["$1"]}" + send cfg "$1" + shift + done +} + +function cfg_set() +{ + var="$1" + shift + cfg["$var"]="$@" + cfg_get "$var" # inform the frontend about the change + var="$(tr '[:upper:]' '[:lower:]' <<<"$var" | tr -d '\n' | tr -c '[:alnum:]' _)" + export cfg_${var}="$@" +} + +function flag() +{ + [ "${flags["$1"]}" ] && return 0 || return 1 +} + +function flag_set() +{ + send flag set "$1" # inform the frontend about the change + flags["$1"]=1 +} + +function flag_unset() +{ + send flag unset "$1" # inform the frontend about the change + unset flags["$1"] +} + +function hdmap_set() +{ + cfg_set hdmap "$( ( echo "$@"; ( echo "$@"; echo "$cfg_hdmap" ) | sort -u -t: -k1,1 ) | sort -u -t: -k2,2 | grep .)" +} + +# Synopsis: hdmap_get <"device"|"mountpoint"|"filesystem"|"automount"> of <"device"|"mountpoint"> <device|mountpoint> +# +# This function returns the given value from the hdmap table +function hdmap_get() +{ + [ "$2" == "of" ] || return 1 + case "$1" in + device) col=1;; + mountpoint) col=2;; + filesystem) col=3;; + automount) col=4;; + *) return 1;; + esac + case "$3" in + device) of_col=1;; + mountpoint) of_col=2;; + *) return 1;; + esac + gawk "BEGIN{FS=\":\"}{if(\$$of_col==\"$4\"){print \$$col}}" <<<"$cfg_hdmap" +} + diff --git a/backend/modules/frontend b/backend/modules/frontend new file mode 100644 index 0000000..ffa2d28 --- /dev/null +++ b/backend/modules/frontend @@ -0,0 +1,21 @@ +#!/bin/bash + +function send() +{ + command="$1" + shift + echo "<acritoxinstaller $command> $@" +} + +function send_error() +{ + if [ "$#" -gt 1 ]; then + send error "$@" >&2 + elif [ "$#" -eq 1 ]; then + send error "$1" "$(tr -d '\n')" >&2 + else + send error 255 unknown >&2 + fi + return 1 +} + diff --git a/backend/modules/hdmap b/backend/modules/hdmap new file mode 100644 index 0000000..d57d105 --- /dev/null +++ b/backend/modules/hdmap @@ -0,0 +1,340 @@ +#!/bin/bash + +# Synopsis: mointpoint_demands +# +# This function dumps the demands of various mountpoints +function mointpoint_demands() +{ +cat <<"EOT" +/: Type:Linux +/boot: LVM:no Type:Linux +/bin: Type:Linux +/etc: Type:Linux +/home: Type:Linux +/lib: Type:Linux +/opt: Type:Linux +/root: Type:Linux +/sbin: Type:Linux +/tmp: Type:Linux +/usr: Type:Linux +/var: Type:Linux +EOT +} + +# FIXME TODO OLD OUTDATED +function emit_error() +{ +send debug "$@" +cat +return 1 +} +# FIXME TODO OLD OUTDATED +function emit_progress() +{ + percent=$1 + [ "$percent" -gt 100 ] && percent=100 + send progress "$percent" +} + + +# Synopsis: is_disk /dev/xyz +# +# This function returns 0 if the supplied argument is a disk. +function is_disk() +{ + stat --format "%t %G" "$1" | grep -qe "^3 " -e " disk$" && return 0 + return 1 +} + +# Synopsis: calculate_min_space +# +# This function estimates the minimum space needed for a hdinstall +function calculate_min_space() +{ + ESTIMATED_ROOT_MIN=$(df -m "/live/filesystem" | tail -1 | gawk '{print $3}') + grep -q squashfs /proc/mounts && ESTIMATED_ROOT_MIN=$(($ESTIMATED_ROOT_MIN*270/100)) + export ESTIMATED_ROOT_MIN +} + +# Synopsis: handle_mountpoint_demands <device> +# +# This function handles the demands of the mountpoints (data from function mountpoint_demands) +# * check if filesystem matches (Filesystem:reiserfs / Filesystem:ext3 / see get_filesystem() ) +# * check if filesystem-type matches (Type:Linux / Type:Windows / see get_filesystem_type() ) +# * check if <device> is a LVM-device (LVM:yes / LVM:no) +# TODO: from old installer, not adapted yet. +function handle_mountpoint_demands() +{ + PART="$1"; + FORMAT_FS="$2"; + POINT=$(echo $3 | cut -d":" -f1); shift 3 + while [ "$1" ]; + do + VAR=$(echo $1 | cut -d":" -f1) + VAL=$(echo $1 | cut -d":" -f2) + case "$VAR" in + Filesystem) + if [ -n "$FORMAT_FS" -a "$FORMAT_FS" != "$VAL" ]; then + echo "ERROR: Filesystem on $PART ($POINT) has to be formatted with $VAL!" \ + | emit_error 1 + return 1 + elif [ -z "$FORMAT_FS" -a "$(get_filesystem "$PART")" != "$VAL" ]; then + echo "ERROR: Filesystem on $PART ($POINT) is not $VAL!" \ + | emit_error 1 + return 1 + fi + ;; + Type) + if [ -n "$FORMAT_FS" -a "$(get_filesystem_type -fs "$FORMAT_FS")" != "$VAL" ]; then + echo "ERROR: Filesystem on $PART ($POINT) has to be formatted with a $VAL-Filesystem!" \ + | emit_error 1 + return 1 + elif [ -z "$FORMAT_FS" -a "$(get_filesystem_type "$PART")" != "$VAL" ]; then + echo "ERROR: Filesystem on $PART ($POINT) is not a $VAL-Filesystem!" \ + | emit_error 1 + return 1 + fi + ;; + LVM) + not=not + lvdisplay $PART &>/dev/null; A=$? + [ "$VAL" = "yes" ] && unset not; B=$? + ((A*B)) || ! ((A-B)) || ( echo ERROR: $PART "($POINT)" must $not be on a LVM-device! | emit_error 1; return 1 ) || return 1 + ;; + esac + shift + done +} + +# Synopsis: check_partitions_for_install +# +# This function processes the hd_map-config: +# * make sure that the device exists +# * take care of the mountpoint demands +# * check if partition has the "automount"-flag +# * check if all partitions are big enough to install the system on it +# TODO: from old installer, not adapted yet. +function check_partitions_for_install() +{ + unset found_root + local progress_steps=$(( $(wc -l <<<"$cfg_hdmap") * 2 + 1)) + local progress=0 + progress=$[progress+1]; emit_progress $[100*progress/progress_steps] + # compute partition_min_table + local partition_min_table_=$ESTIMATED_ROOT_MIN + while IFS=: read device mountpoint filesystem automount + do + case "$mountpoint" in + "") continue;; + /) continue;; + /usr) MP_MIN=$(( $ESTIMATED_ROOT_MIN - $(du -sm --exclude /live/filesystem/usr /live/filesystem | cut -f1) ));; + *) MP_MIN=$(du -sm "/live/filesystem$mountpoint" 2>/dev/null | cut -f1);; + esac + [ -z "$MP_MIN" ] && MP_MIN=0 + mp="$mountpoint" + while mp="$(dirname "$mp")" + do + var_mp="$(echo "$mp" | sed 's/[^a-zA-Z0-9]/_/g')" + parent_min="$(eval echo \$partition_min_table$var_mp)" + if [ -n "$parent_min" ]; then + eval local partition_min_table$var_mp=$(( $parent_min-$MP_MIN )) + break + fi + [ "${#mp}" -gt 1 ] || break; + done + var_mp="$(echo "$mountpoint" | sed 's/[^a-zA-Z0-9]/_/g')" + eval local partition_min_table$var_mp=$MP_MIN + progress=$[progress+1]; emit_progress $[100*progress/progress_steps] + done <<<"$cfg_hdmap" + + isosrc_dev="$(awk '{if($2 == "/isosrc"){print $1}}' /proc/mounts)" + while IFS=: read device mountpoint filesystem automount + do + [ -z "$mountpoint" ] && continue; + + # set flag if there is a root-partition in the hd_map + [ "$mountpoint" = / ] && found_root=1 + + if [ "$device" = "$isosrc_dev" ]; then + if [ "$filesystem" ]; then + emit_error 1 "Partition $device ($mountpoint) is mounted to /isosrc... This partition cannot be formatted!" + return 1 + fi + fi + + # take care of the mountpoint demands + if part_demands="$(mointpoint_demands | egrep "^$mountpoint:" 2>/dev/null)"; then + [ "$automount" = "auto" ] || emit_error 1 "Partition $device ($mountpoint) doesn't have the automount-flag set!" || return 1 + eval handle_mountpoint_demands \"$device\" \"$filesystem\" $part_demands + fi + + # Check if the partition is big enough to contain the installation + var_mp="$(echo "$mountpoint" | sed 's/[^a-zA-Z0-9]/_/g')" + mp_min="$(eval echo \$partition_min_table$var_mp)" + partition_size_min=$[mp_min*1024*1024*115/100] # + 15% Filesystem overhead + partition_size="$(blockdev --getsize64 $device)" # actual size of device (in bytes) + if [ "$partition_size" -lt "$partition_size_min" ]; then + emit_error 1 "Partition $device ($mountpoint) is too small! it is $[partition_size/1024/1024] MB big, but it should be at least $[partition_size_min/1024/1024+10] MB big" + return 1 + fi + progress=$[progress+1]; emit_progress $[100*progress/progress_steps] + done <<<"$cfg_hdmap" + + if [ -z "$found_root" ]; then + echo "No root-partition selected!" | emit_error 1 + fi +} + +# Synopsis: umount_all_affected [-fdisk] <device> +# +# This function unlocks a device and all affected devices: +# * it umounts mounted partitions with "umount" and disables swap-partitions with "swapoff" +# * if "-fdisk" is set: +# - it unlocks all partitions that are on the same device as the one given +# (e.g. "umount_all_affected -fdisk /dev/hda3" is called, so /dev/hda* is unlocked) +# - it takes care of LVM-Volumes and unlocks them if they are affected +# - it takes care of dm_crypt-Disks and unlocks them if they are affected +# TODO: from old installer, not fully adapted yet. +function umount_all_affected() +{ + unset DEV NR EXHAUSITIVE + if [ "$1" = "-fdisk" ]; then + # partition itself and its "sister" partitions (just to be sure, for fdisk): + shift + #DEV="${1%%[0-9]*}" + DEV="$(get_disk "$1")" + NR="${1:${#disk}}" + EXHAUSITIVE=1 + fi + [ -z "$DEV" ] && DEV="$(echo "$1" | dereferce_links_in_list)" + # Mounts + while IFS=" " read mnt_dev mnt_point mnt_dummy + do + [ "$mnt_point" = "/live/filesystem" -o -z "$mnt_point" ] && continue + case "$mnt_point" in + /|/cdrom|/dev|/dev/*|/isosrc|/proc|/proc/*|/ramdisk|/sys|/tmp) ;; + *) + echo $mnt_dev | dereferce_links_in_list | grep -q ^$DEV$ || continue + for umount_point in $(gawk '{print $2}' /proc/mounts | grep -e "^$mnt_point$" -e "^$mnt_point/" | sort -r) + do + fuser -km "$umount_point" + umount "$umount_point" &>/dev/null || \ + umount -l "$umount_point" + done + ;; + esac + done < /proc/mounts + # Swap + for i in $(grep -e "^$DEV" /proc/swaps | cut -d\ -f1) + do + swapoff "$i"; + done +# # LVM +# for i in $(pvdisplay -c 2>/dev/null | grep "$DEV" | cut -d: -f2 | sort | uniq) +# do +# lv_name="$(lvdisplay $i | gawk '/LV Name/{print $3}')" +# lv_dev="$(echo $lv_name | dereferce_links_in_list)" +# for dev in $( ( echo $lv_name; echo $lv_dev ) | sort | uniq) +# do +# # recursive function call +# umount_all_affected $dev +# done +# ((EXHAUSITIVE)) && vgchange -a n $i &>/dev/null +# done +# # Crypttab +# for cmapname in $(grep $DEV /etc/crypttab | cut -d\ -f1) +# do +# umount_all_affected "/dev/mapper/$cmapname" +# ((EXHAUSITIVE)) && cryptsetup remove $cmapname +# done +} + +# Synopsis: prepare_partitions_for_install [--nomount] +# +# This function processes the hd_map-config: +# * create mountpoints +# * format the partitions if a filesystem is given +# * take care of LVM-Volumes and dm_crypt-Disks +# * create the specified mountpoints in $TARGET +# * mount the partitions to the target +# * mount (bind) /dev, /proc and /sys to the target +# +# --nomount simply doesn't mount or umount partitions +# TODO: from old installer, not adapted yet. +function prepare_partitions_for_install() +{ + send install_step prepare_partitions_for_install + emit_progress 0 + local progress_steps=$(( $(wc -l <<<"$cfg_hdmap") )) + local progress=0 + while IFS=: read device mountpoint filesystem automount + do + [ "$1" != "--nomount" ] && umount_all_affected $device + + # format device with filesystem (if specified) + if [ "$filesystem" ]; then + + dd if=/dev/zero of=$device bs=1k count=16 >/dev/null 2>/dev/null # shutup! :-) + + TMP=/tmp/mkfs.$$ + case "$filesystem" in + xfs) + mkfs.$filesystem -f $device 2> $TMP 1>&2 + ;; + reiser*) + echo y | mkfs.$filesystem $device 2> $TMP 1>&2 + ;; + jfs) + echo y | mkfs.$filesystem $device 2> $TMP 1>&2 + ;; + *) + mkfs.$filesystem $device 2> $TMP 1>&2 + ;; + esac + + RC="$?" + if [ $RC -ne 0 ]; then + ERROR_MESSAGES=$(tail -8 $TMP) + echo "$ERROR_MESSAGES" + emit_error 1 "mkfs failed" || return 1 + fi + + # Deactivate dir_index-feature of ext2/ext3/ext4-partitions + case $filesystem in + *ext*) + tune2fs -O ^dir_index $device &>/dev/null + ;; + esac + fi + + mkdir -p ${TARGET}${mountpoint} # make sure mountpoint exists + + # only mount the partition if: 1. it has the automount flag + # 2. the mountpoint exists on the Live system + # and 3. prepare_partitions_for_install was not called with "--nomount" + if [ "$automount" = "auto" -a "$1" != "--nomount" -a -d "/live/filesystem$mountpoint" ]; then + # mount device to mountpoint + EC="$(LC_ALL=C mount $device ${TARGET}${mountpoint} 2>&1)" + if (($?)); then + case "$EC" in + "*already mounted*") # then let's try "mount --bind" + already_mp="$(grep ^$device /proc/mounts | cut -d\ -f2)" + if [ -d "$already_mp" ]; then + awk '/^\/dev/{if($4 ~ /^rw/){print $1}}' /proc/mounts | grep -qw $device || mount -o remount,rw "$already_mp" + mount --bind "$already_mp" ${TARGET}${mountpoint} 2>&1 + fi + ;; + *) + emit_error 1 "mount failed: $EC" || return 1 + ;; + esac + fi + if ! awk '/^\/dev/{if($4 ~ /^rw/){print $1}}' /proc/mounts | grep -qw $device; then + emit_error 1 "mount failed: $EC" || return 1 + fi + fi + + # update progress + progress=$[progress+1]; emit_progress $[100*progress/progress_steps] + done <<<"$cfg_hdmap" +} diff --git a/backend/modules/init b/backend/modules/init new file mode 100644 index 0000000..f7a7628 --- /dev/null +++ b/backend/modules/init @@ -0,0 +1,11 @@ +#!/bin/bash + +function init_installer() +{ + [ -f /etc/default/distro ] && . /etc/default/distro + export FLL_DISTRO_MODE FLL_DISTRO_NAME FLL_LIVE_USER + mkdir -p /live/filesystem + [ -d /live/filesystem/usr ] || mount -o ro /dev/loop0 /live/filesystem + cfg_set hostname "${FLL_DISTRO_NAME}Box" +} + diff --git a/backend/modules/install b/backend/modules/install new file mode 100644 index 0000000..760f40d --- /dev/null +++ b/backend/modules/install @@ -0,0 +1,75 @@ +#!/bin/bash + +function do_install() +{ + send install_step check_partitions_for_install + check_partitions_for_install + prepare_target + prepare_partitions_for_install + copy_system_to_target + update_fstab_on_target + update_passwd_on_target + copy_home_to_target + copy_etc_to_target + configure_target_update_files + configure_target_purge_live_only_stuff + configure_target_services + install_bootmanager_to_target + send install_step cleanup + cleanup +} + +function prepare_target() +{ + send install_step prepare_target + mkdir -p /live/hdinstall + export TARGET=/live/hdinstall +} + +# Synopsis: chroot_it <...> +# +# execute the supplied command in the target +function chroot_it() +{ + [ -n "$TARGET" -a $UID -eq 0 ] && chroot $TARGET "$@" +} + +# Synopsis: copy_system_to_target +# +# This function copies the system to the target. +# Therefore $TARGET and all partitions of hd_map have to be mounted +# this should have be done in the prepare-stage (see prepare_partitions_for_install) +# +function copy_system_to_target() +{ + send install_step copy_system_to_target + emit_progress 0 + calculate_min_space + orig_size="$ESTIMATED_ROOT_MIN" + dest_size_before=$(di -dm -fSMu | gawk '/\/live\/hdinstall/{used+=int($3)} END{print int(used)}') + dest_size_diff=0 + + cd /live/filesystem + cp -a * $TARGET & + + cp=$! + old_percent=0 + while ps --pid $cp &>/dev/null + do + dest_size=$(di -dm -fSMu | gawk '/\/live\/hdinstall/{used+=int($3)} END{print int(used)}') + dest_size_diff=$(( $dest_size - $dest_size_before )) + percent=$((( 100 * $dest_size_diff ) / $orig_size )) + if [ "$percent" != "$old_percent" ]; then + emit_progress $percent + old_percent="$percent" + fi + sleep 5 + done + + sync + mkdir -p "$TARGET/proc" "$TARGET/dev" "$TARGET/sys" + mount --bind /proc "$TARGET/proc" + mount --bind /dev "$TARGET/dev" + mount --bind /sys "$TARGET/sys" +} + diff --git a/backend/modules/install_configure b/backend/modules/install_configure new file mode 100644 index 0000000..28e351e --- /dev/null +++ b/backend/modules/install_configure @@ -0,0 +1,152 @@ +#!/bin/bash + +# Synopsis: configure_target_update_files +# +# This function is adapted from the Knoppix-Installer +function configure_target_update_files() +{ + send install_step configure_target_update_files + # set up hostname + cat <<EOF >$TARGET/etc/hosts +127.0.0.1 localhost +127.0.1.1 $cfg_hostname + +# The following lines are desirable for IPv6 capable hosts +# (added automatically by netbase upgrade) + +::1 ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +ff02::3 ip6-allhosts +EOF + echo "$cfg_hostname" > $TARGET/etc/hostname + echo "$cfg_hostname" > $TARGET/etc/mailname + + # remove LiveCD-user from /etc/sudoers + cat > "$TARGET/etc/sudoers" <<EOF +# /etc/sudoers +# +# This file MUST be edited with the 'visudo' command as root. +# +# See the man page for details on how to write a sudoers file. +# + +Defaults env_reset + +# Host alias specification + +# User alias specification + +# Cmnd alias specification + +# User privilege specification +root ALL=(ALL) ALL +EOF + chown root:root "$TARGET/etc/sudoers" + chmod 0440 "$TARGET/etc/sudoers" + + # "normalize" /etc/inittab + rm -f "$TARGET/etc/inittab" + sed 's/id\:[0-6]\:initdefault\:/id\:5\:initdefault\:/;s/\([1-6]:23\):/\145:/' "$TARGET/usr/share/sysvinit/inittab" > "$TARGET/etc/inittab" + + # create "real" /tmp with mode 1777 + rm -f $TARGET/tmp 2>/dev/null + mkdir -p $TARGET/tmp + chmod 1777 $TARGET/tmp + + # create /etc/mtab as a regular file + rm -f $TARGET/etc/mtab + touch $TARGET/etc/mtab + + # configure /etc/kernel-pkg.conf + if [ -f "$TARGET/etc/kernel-pkg.conf" ]; then + perl -pi -e "s/^maintainer.*\=.*/maintainer \:\= $cfg_realname/;s/^email.*\=.*/email \:\= $cfg_username\@$cfg_hostname\.local/" "$TARGET/etc/kernel-pkg.conf" + NUMCPUS=$(grep -c "model name" /proc/cpuinfo) + [ $NUMCPUS -ge 2 ] && echo CONCURRENCY_LEVEL := $NUMCPUS >> $TARGET/etc/kernel-pkg.conf + fi + + # enable KDE sounds + rm -f "$TARGET/home/$cfg_username/.kde/share/config/knotifyrc" + + # profile + cat "$TARGET/usr/share/base-files/profile" > "$TARGET/etc/profile" + + # For us users use an us-mirror + case "$LANGUAGE" in + us*) + #perl -pi -e "s/ftp2.de.debian.org/ftp.uk.debian.org/" $TARGET/etc/apt/sources.list + : + ;; + esac + + # install hooks + if [ "$(ls $TARGET/usr/share/acritoxinstaller/target-config)" ]; then + for hook in $TARGET/usr/share/acritoxinstaller/target-config/* + do + chroot_it "${hook#$TARGET}" + done + fi + + # install overlay + if [ "$(ls $TARGET/usr/share/acritoxinstaller/target-overlay)" ]; then + cp -a --target-directory=$TARGET $TARGET/usr/share/acritoxinstaller/target-overlay/* + fi + + # add correct keymap + [ -f /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard + + [ -n "$KEYTABLE" ] && chroot_it install-keymap "$KEYTABLE" 2>/dev/null +} + +# Synopsis: configure_target_purge_live_only_stuff +# +# This function removes everything that is only useful on live-systems +function configure_target_purge_live_only_stuff() +{ + send install_step configure_target_purge_live_only_stuff + # remove live-only-packages + chroot_it dpkg --purge \ + busybox \ + acritoxinstaller \ + acritoxinstaller-kanotix \ + live-boot-initramfs-tools \ + live-boot \ + live-initramfs \ + live-build-cgi \ + live-build \ + live-helper \ + live-config-runit \ + live-config-sysvinit \ + live-config-upstart \ + live-config \ + live-magic \ + live-manual-epub \ + live-manual-html \ + live-manual-odf \ + live-manual-pdf \ + live-manual-txt \ + live-manual \ + mknbi \ + syslinux \ + tftpd-hpa &> /dev/null + + # disable live config + [ -f "$TARGET/etc/default/distro" ] && \ + perl -pi -e "s/^FLL_DISTRO_MODE\=.*/FLL_DISTRO_MODE\=\"installed\"/" "$TARGET/etc/default/distro" + + # remove temporary kde- user files + rm -f "$TARGET/home/$cfg_username/.DCOPserver_*_*" + rm -f "$TARGET/home/$cfg_username/.kde/cache-*" + rm -f "$TARGET/home/$cfg_username/.kde/socket-*" + rm -f "$TARGET/home/$cfg_username/.kde/tmp-*" + rm -f "$TARGET/home/$cfg_username/.*uthority" + + rm -rf "$TARGET/etc/sysconfig" + rm -f "$TARGET/home/$cfg_username/Desktop/install-gui.desktop" + + # remove kdm live shutdown hack + rm -f "$TARGET/home/$cfg_username/.kde/shutdown/kdm-force-shutdown-hack" +} + diff --git a/backend/modules/install_main b/backend/modules/install_main new file mode 100644 index 0000000..bee41af --- /dev/null +++ b/backend/modules/install_main @@ -0,0 +1,302 @@ +#!/bin/bash + +# Synopsis: update_fstab_on_target +# +# This function is partly adapted from the Knoppix-Installer +# It creates a new fstab for the new installed system in $TARGET. +# * proc, usbfs, sysfs, tmpfs: hardcoded +# * all mountpoints of the hd_map +# * cdroms, floppy +# * remove not needed device links +function update_fstab_on_target() +{ + send install_step update_fstab_on_target + emit_progress 0 + local progress_steps=$(( $(wc -l <<<"$cfg_hdmap") + 2 )) + local progress=0 + + # Charset stuff for FAT/NTFS-Filesystems + unset utf_option nls + if [ "$(locale charmap)" = "UTF-8" ]; then + utf_option=",utf8" + nls=",nls=utf8" + fi + chroot_it locale-gen &>/dev/null + + # Build new /etc/fstab + cat <<EOF >$TARGET/etc/fstab +# /etc/fstab: static file system information. +# +# <file system> <mount point> <type> <options> <dump> <pass> +proc /proc proc defaults 0 0 +EOF + + [ -x $TARGET/etc/init.d/mountkernfs.sh ] || cat <<EOF >>$TARGET/etc/fstab +sysfs /sys sysfs defaults 0 0 +tmpfs /dev/shm tmpfs defaults 0 0 +EOF + + while IFS=: read device mountpoint filesystem automount + do + fstab_options=""; fstab_dump=0; fstab_pass=2; fstab_type="" + [ -z "$fstab_type" ] && fstab_type=$filesystem + [ -z "$fstab_type" ] && fstab_type=$(get_filesystem $device) + [ -z "$fstab_type" ] && fstab_type=auto + + case "$automount" in + auto) + fstab_options="defaults";; + *) + fstab_options="noauto,users";; + esac + + case "$fstab_type" in + msdos) + fstab_options="${fstab_options},umask=000,quiet${utf_option}"; fstab_pass=0;; + vfat) + fstab_options="${fstab_options},umask=000,shortname=mixed,quiet${utf_option}"; fstab_pass=0;; + esac + + if [ "$mountpoint" = "/" ]; then + fstab_pass=1 + case $fstab_type in + reiser*|xfs|jfs) + fstab_options="defaults" + ;; + *) + fstab_options="defaults,errors=remount-ro" + ;; + esac + elif [ "${mountpoint:0:7}" = "/media/" ]; then + # don't run fsck on boot for all /media/* mountpoints + fstab_pass=0 + else + # don't run fsck on boot if device is a removable disk (if group of /dev/XXX == floppy) + [ "$(stat --format "%G" $device)" = "floppy" ] && fstab_pass=0 + fi + + fstab_options="${fstab_options##defaults,}" + + unset DEV UUID + case $device in + /dev/mapper/*) ;; + /dev/disk/by-uuid/*) DEV=/dev/$(readlink $device|sed s@../../@@) + UUID="UUID=${device#/dev/disk/by-uuid/}" + ;; + /dev/*) DEV=$device + UUID="UUID=$(get_partition_uuid $device)" + ;; + UUID=*) UUID=$device + DEV=/dev/$(readlink /dev/disk/by-uuid/${device#UUID=}|sed s@../../@@) + ;; + esac + + [ -n "${DEV#/dev/}" ] && echo "# $DEV" >> $TARGET/etc/fstab + if [ -n "${UUID#UUID=}" ]; then + printf "%-15s %-15s %-7s %-15s %-7s %s\n" "$UUID" "$mountpoint" "$fstab_type" "$fstab_options" "$fstab_dump" "$fstab_pass" >> $TARGET/etc/fstab + else + # this partition doesn't have an UUID + printf "%-15s %-15s %-7s %-15s %-7s %s\n" "$device" "$mountpoint" "$fstab_type" "$fstab_options" "$fstab_dump" "$fstab_pass" >> $TARGET/etc/fstab + fi + + # Remove not needed device links + [ "/media/${device##*/}" != "$mountpoint" ] && rmdir "$TARGET/media/${device##*/}" &>/dev/null + rm -f "$TARGET/home/$cfg_username/Desktop/${device##*/}" + + # update progress + progress=$[progress+1]; emit_progress $[100*progress/progress_steps] + done <<<"$cfg_hdmap" + + # Add swap to /etc/fstab + while read device + do + UUID="$(get_partition_uuid $device)" + if [ -z "$UUID" ]; then + # swap partition without UUID + swapoff $device + mkswap $device + swapon $device + UUID="$(get_partition_uuid $device)" + fi + [ -z "$UUID" ] && continue # should never happen... + + printf "%-15s %-15s %-7s %-15s %-7s %s\n" "UUID=$UUID" "none" "swap" "sw" "0" "0" >> $TARGET/etc/fstab + done < <(list_swap_partitions) + + # Add cdrom devices to /etc/fstab + + CDROM=0 + for c in $(gawk '/name/{for (i=NF;i>=3;i--) {print $i}}' /proc/sys/dev/cdrom/info 2>/dev/null); do + [ -d $TARGET/media/cdrom$CDROM ] || mkdir -p $TARGET/media/cdrom$CDROM + if [ "$CDROM" = "0" ]; then + if [ "$(readlink $TARGET/media/cdrom)" != "cdrom0" ]; then + rm -f $TARGET/media/cdrom + ln -s cdrom0 $TARGET/media/cdrom + fi + if [ "$(readlink $TARGET/cdrom)" != "media/cdrom" ]; then + rm -f $TARGET/cdrom + ln -s media/cdrom $TARGET/cdrom + fi + fi + printf "%-15s %-15s %-7s %-15s %-7s %s\n" "/dev/$c" "/media/cdrom$CDROM" "udf,iso9660" "user,noauto" "0" "0" >> $TARGET/etc/fstab + CDROM=$(($CDROM+1)) + done + if [ "$CDROM" = "0" ]; then + rm -f $TARGET/cdrom $TARGET/media/cdrom + fi + + # Add floppy devices to /etc/fstab + + for f in $(ls -d /sys/block/fd* 2>/dev/null); do + [ -d $TARGET/media/floppy${f#/sys/block/fd} ] || mkdir -p $TARGET/media/floppy${f#/sys/block/fd} + printf "%-15s %-15s %-7s %-15s %-7s %s\n" "/dev${f#/sys/block}" "/media/floppy${f#/sys/block/fd}" "auto" "rw,user,noauto" "0" "0" >> $TARGET/etc/fstab + done + +} + +# Synopsis: update_passwd_on_target +# +function update_passwd_on_target() +{ + send install_step update_passwd_on_target + chroot $TARGET sh -c "usermod --password '$cfg_rootpwd' root" + + if [ -x $ROOT/usr/sbin/adduser ]; then + LC_ALL=C chroot $TARGET adduser --disabled-password --force-badname --no-create-home --gecos "$cfg_realname,,," --uid 1000 "$cfg_username" >/dev/null + else + chroot $TARGET useradd -c "$cfg_realname,,," "$cfg_username" -u 1000 >/dev/null + fi + + chroot $TARGET sh -c "usermod --password '$cfg_userpwd' '$cfg_username'" + + for group in lpadmin scanner; do + chroot $TARGET addgroup --system $group >/dev/null 2>&1 + done + for group in adm audio cdrom dialout floppy video plugdev dip lpadmin lp scanner powerdev netdev; do + chroot $TARGET adduser --force-badname "$cfg_username" $group >/dev/null 2>&1 + done +} + +# Synopsis: copy_home_to_target +# +# This function copies the home directory from the live user +function copy_home_to_target() +{ + send install_step copy_home_to_target + #check if already data is there then stop + if [ -d "$TARGET/home/$cfg_username" ]; then + chroot "$TARGET" chown -R "$cfg_username":"$cfg_username" "/home/$cfg_username" + return 0 + fi + + if [ -d "/home/$FLL_LIVE_USER/.kde" ]; then + rm -rf "$TARGET/home/$FLL_LIVE_USER" + cp -a "/home/$FLL_LIVE_USER" "$TARGET/home" + [ "$cfg_username" != "$FLL_LIVE_USER" ] && mv "$TARGET/home/$FLL_LIVE_USER" "$TARGET/home/$cfg_username" + else + cp -a "$TARGET/etc/skel" "$TARGET/home" + mv "$TARGET/home/skel" "$TARGET/home/$cfg_username" + fi + + # update home-path in user's config files + if [ "$cfg_username" != "$FLL_LIVE_USER" ]; then + rm -f "$TARGET/home/$cfg_username/.mozilla/appreg" + rm -f "$TARGET/home/$cfg_username/.mozilla/pluginreg.dat" + if [ -e "$TARGET/home/$cfg_username/.mozilla/$FLL_LIVE_USER" ]; then + [ -e "$TARGET/home/$cfg_username/.mozilla/default" ] || mv "$TARGET/home/$cfg_username/.mozilla/$FLL_LIVE_USER" "$TARGET/home/$cfg_username/.mozilla/default" + perl -pi -e 's/.*general.useragent.*\n?//' "$TARGET/home/$cfg_username/.mozilla/default/*/prefs.js" + fi + + OLDHOME="/home/$FLL_LIVE_USER" + NEWHOME="/home/$cfg_username" + PART="$TARGET" + for f in $(find "$PART$NEWHOME" -exec grep -ls "$OLDHOME" {} \;|grep -v $0); do + perl -pi -e "s|$OLDHOME|$NEWHOME|g" "$f" + done + fi + + # revert to plain debian .bashrc + cat "$TARGET/etc/skel/.bashrc" > "$TARGET/home/$cfg_username/.bashrc" + + # revert kdesu/sudo workaround + rm -f "$TARGET/home/$cfg_username/.kde/share/apps/konsole/su.desktop" \ + "$TARGET/home/$cfg_username/.kde/share/apps/konsole/sumc.desktop" \ + "$TARGET/home/$cfg_username/.kde/share/config/kdesurc" \ + "$TARGET/home/$cfg_username/.kde4/share/config/kdesurc" \ + "$TARGET/home/$cfg_username/.su-to-rootrc" + rm -rf "$TARGET/home/$cfg_username/.gconf/apps/gksu" + + # force kde first time configuration + if [ -f /etc/skel/.kde/share/config/kpersonalizerrc ]; then + perl -pi -e 's/FirstLogin=false/FirstLogin=true/g' "$TARGET/etc/skel/.kde/share/config/kpersonalizerrc" + + # The users kde should be perfect, unless we just copied from template ... + [ ! -d "/home/$FLL_LIVE_USER/.kde" ] && perl -pi -e 's/FirstLogin=false/FirstLogin=true/g' "$TARGET/home/$cfg_username/.kde/share/config/kpersonalizerrc" + fi + + chroot "$TARGET" chown -R "$cfg_username":"$cfg_username" "/home/$cfg_username" +} + +# Synopsis: copy_etc_to_target +# +# This function is partly adapted from the Knoppix-Installer +function copy_etc_to_target() +{ + send install_step copy_etc_to_target + # UTC=no fix + if [ -f /etc/default/rcS -a -f $TARGET/etc/default/rcS ]; then + cat /etc/default/rcS > $TARGET/etc/default/rcS + fi + + cp -a /etc/timezone $TARGET/etc/timezone + cp -a /etc/localtime $TARGET/etc/localtime + cp -a /etc/default/keyboard $TARGET/etc/default/keyboard + cp -a /etc/default/locale $TARGET/etc/default/locale + cp -a /etc/locale.gen $TARGET/etc/locale.gen + #cp -a /etc/console/* $TARGET/etc/console/ + #cp -a /etc/environment $TARGET/etc/environment + + # network + rm -f $TARGET/etc/network/interfaces + cp -a /etc/network/interfaces $TARGET/etc/network/interfaces + + # create locales + chroot_it locale-gen &>/dev/null + chroot_it dpkg-reconfigure -fnoninteractive keyboard-configuration &>/dev/null + + # nvidia autoinstall trigger + chroot_it update-rc.d -f kanotix remove &>/dev/null + rm -f $TARGET/etc/init.d/kanotix + + # xorg.conf + debconf-get-selections | grep -e xserver-xorg -e tzdata | chroot_it debconf-set-selections &>/dev/null + rm -f $TARGET/etc/X11/xorg.conf* + chroot_it dpkg-reconfigure -phigh xserver-xorg &>/dev/null + + # Save ALSA sound volume + if [ -e /proc/asound/modules ] && [ -x /usr/sbin/alsactl ]; then + /usr/sbin/alsactl store + if [ -f /var/lib/alsa/asound.state ]; then + cp /var/lib/alsa/asound.state "$TARGET/var/lib/alsa" + fi + fi + + # KDM: auto login + kdmrc=$TARGET/etc/kde3/kdm/kdmrc + [ -f $TARGET/etc/kde4/kdm/kdmrc ] && kdmrc=$TARGET/etc/kde4/kdm/kdmrc + if [ -e $kdmrc ]; then + perl -pi -e "s|^[#\s]*(AutoLoginUser).*|\1=$cfg_username|" $kdmrc + [ "$cfg_autologin" = "on" ] && autologin="true" || autologin="false" + perl -pi -e "s|^[#\s]*(AutoLoginEnable).*|\1=$autologin|" $kdmrc + fi + + # Crypto + cp -a /etc/crypttab $TARGET/etc/crypttab + + # PolicyKit + if [ -e /etc/PolicyKit/PolicyKit.conf -a -e $TARGET/etc/PolicyKit/PolicyKit.conf ]; then + sed '/<!-- .* user in live session -->/d; s/user="'"$FLL_LIVE_USER"'"/user="'"$cfg_username"'"/;' \ + < /etc/PolicyKit/PolicyKit.conf > $TARGET/etc/PolicyKit/PolicyKit.conf + fi +} + diff --git a/backend/modules/install_services b/backend/modules/install_services new file mode 100644 index 0000000..e3b74c3 --- /dev/null +++ b/backend/modules/install_services @@ -0,0 +1,19 @@ +#!/bin/bash + +# Synopsis: configure_target_services +# +# This function configures the services and their autostart +function configure_target_services() +{ + send install_step configure_target_services + # prepare ssh + if [ /etc/init.d/ssh ]; then + if [ ! -e "$TARGET/etc/ssh/ssh_host_rsa_key" ]; then + ssh-keygen -q -t rsa -f "$TARGET/etc/ssh/ssh_host_rsa_key" -C '' -N '' + fi + if [ ! -e "$TARGET/etc/ssh/ssh_host_dsa_key" ]; then + ssh-keygen -q -t dsa -f "$TARGET/etc/ssh/ssh_host_dsa_key" -C '' -N '' + fi + fi +} + diff --git a/backend/modules/partitions b/backend/modules/partitions new file mode 100644 index 0000000..0d59323 --- /dev/null +++ b/backend/modules/partitions @@ -0,0 +1,251 @@ +#!/bin/bash + +# Synopsis: list_all_disks +# +# This function lists all disks +# Output example: +# /dev/sda +# /dev/sdb +function list_all_disks() +{ + awk -vli="$(awk '{if($2=="sd") print $1;}' /proc/devices)" 'BEGIN{m=split(li,list," ")}{for(i=1;i<=m;i++) if($1==list[i]&&$2%16==0) print "/dev/"$4;}' /proc/partitions +} + +# Synopsis: send_list_of_disks +# +# This script sends a list of all disks with size-details to the frontend. +# Output example: +# <installer data> list_of_disks +# /dev/sda 10001908224 +# /dev/sdb 64023257088 +function send_list_of_disks() +{ + send data list_of_disks + list_all_disks | partitions_size_details +} + +# Synopsis: list_all_partitions +# +# This function lists all partitions from all disks +# Output example: +# /dev/sda1 +# /dev/sda2 +# /dev/sdb5 +function list_all_partitions() +{ + awk -vli="$(awk '{if($2=="sd") print $1;}' /proc/devices)" 'BEGIN{m=split(li,list," ")}{for(i=1;i<=m;i++) if($1==list[i]&&$2%16!=0) print "/dev/"$4;}' /proc/partitions +} + +# Synopsis: (e.g.) list_all_partitions | partitions_usage_details +# +# This function lists usage details for a list of partitions from STDIN +# Output example: +# /dev/sda1 filesystem reiserfs +# /dev/sda2 filesystem ext3 +# /dev/sda3 other swap +function partitions_usage_details() +{ + while read part x + do + [ -e "$part" ] || continue + ID_FS_USAGE="$(/sbin/blkid -p -s USAGE -o value "$part")" + [ "$ID_FS_USAGE" ] || continue + ID_FS_TYPE="$(/sbin/blkid -p -s TYPE -o value "$part")" + echo "$part $ID_FS_USAGE $ID_FS_TYPE" + done +} + +# Synopsis: (e.g.) list_all_partitions | partitions_size_details +# +# This function lists size details for a list of partitions from STDIN +# Output example: +# /dev/sda 64023257088 +# /dev/sda1 10001908224 +function partitions_size_details() +{ + while read part x + do + [ -e "$part" ] || continue + echo "$part $(blockdev --getsize64 "$part")" + done +} + +# Synopsis: list_partitions [-type <filesystem>] [-disk <disk>] [-usage <usage>] +# +# This function lists all partitions that match all the given parameters +# Output example: +# /dev/sda1 +# /dev/sda2 +# /dev/sdb5 +function list_partitions() +{ + unset required_type required_disk; + required_usage="filesystem" + + while [ "$1" ] + do + case $1 in + -type) + required_type="$2"; + shift + ;; + -disk) + required_disk="$2"; + shift + ;; + -usage) + required_usage="$2"; + shift + ;; + esac + shift + done + + while IFS=" " read part usage type + do + if [ "$usage" = "$required_usage" ]; then + [ "$required_type" -a "$required_type" != "$(get_filesystem $part)" ] && continue + [ "$required_disk" ] && ! echo "$part" | grep -q "^$required_disk" && continue + echo $part + fi + done < <(list_all_partitions | partitions_usage_details) +} + + +# Synopsis: list_linux_partitions +# +# This function lists all partitions from the disks (by list_all_disks) which have partition Id 0x83 (= Linux) +# Output example: +# /dev/sda4 +# /dev/sdb1 +function list_linux_partitions() +{ + for disk in $(list_all_disks) + do + LC_ALL=C sfdisk -l "$disk" 2>/dev/null | sed 's/[*+]//g;' | gawk '/^\/dev/{if($6 == 83){print $1}}' + done +} + +# Synopsis: list_swap_partitions +# +# This function lists all partitions from the disks (by list_all_disks) which have partition Id 0x82 (= Linux swap) +# Output example: +# /dev/sda4 +# /dev/sdb1 +function list_swap_partitions() +{ + for disk in $(list_all_disks) + do + LC_ALL=C sfdisk -l "$disk" 2>/dev/null | sed 's/[*+]//g;' | gawk '/^\/dev/{if($6 == 82){print $1}}' + done +} + +# Synopsis: get_disk <partition> +# +# This function returns the disk containing the given partition +# Output example: +# /dev/sda +function get_disk() +{ + path="$(udevadm info -q path -n "$1")" + while [ "$path" ] + do + udevadm info -q env -p "$path" | grep -q "^DEVTYPE=disk$" && break + path="$(dirname "$path")" + done + [ "$path" ] && udevadm info --root -q name -p "$path" && return 0 + return 1 +} + +# Synopsis: is_removeable <disk/partition> +# +# This function checks if a disk or partition is removeable (returncode 0) or not (returncode 1) +function is_removeable() +{ + DEV="$(get_disk "$1")" + REM=$(cat /sys/block/${DEV#/dev/}/removable 2>/dev/null) + case $(readlink -f /sys/block/${DEV#/dev}) in *usb*) REM=1; esac + [ "$REM" = "1" ] && return 0 || return 1 +} + +# Synopsis: list_possible_root_partitions +# +# This script lists all possible root-partitions. +# * all linux-partitions and all partitions that have a linux-filesystem +# Output example: +# /dev/sda4 +# /dev/sdb1 +function list_possible_root_partitions() +{ + ( list_linux_partitions; list_partitions -type Linux ) | sort -u +} + +# Synopsis: send_possible_root_partitions +# +# This script sends a list of all possible root-partitions with size-details to the frontend. +# Output example: +# <installer data> possible_root_partitions +# /dev/sda4 10001908224 +# /dev/sdb1 64023257088 +function send_possible_root_partitions() +{ + send data possible_root_partitions + list_possible_root_partitions | partitions_size_details +} + +# Synopsis: send_possible_root_filesystems +# +# This script sends a list of all possible filesystems to format the root-partition with to the frontend. +# Output example: +# <installer data> possible_root_filesystems +# ext4 +# ext3 +# reiserfs +function send_possible_root_filesystems() +{ + send data possible_root_filesystems + for fs in ext4 ext3 reiserfs xfs jfs; do echo $fs; done +} + +# Synopsis: get_filesystem <device> +# +# This function returns the filesystem on the supplied device. +# Returned filesystem could be: +# ext4, ext3, ext2, reiserfs, xfs, minix, hfs, efs, reiser4, +# jfs, iso9660, vfat, ntfs, swap, oracleasm, jbd, gfs, +# gfs2, vxfs, romfs, bfs, cramfs, qnx4, udf, ufs, hpfs, +# sysv, swsuspend, ocfs, ocfs2 +# Output example: +# ext4 +function get_filesystem() +{ + [ -x /sbin/blkid ] && /sbin/blkid -s TYPE -o value "$1" +} + +# Synopsis: get_filesystem_type [-fs <filesystem>]|<device> +# +# This function returns the type of the filesystem on the supplied device (or filesystem). +# Returned type could be: +# Linux, CD-ROM, Windows, Swap, (not recognized type -> filesystem) +# Output example: +# Linux +function get_filesystem_type() +{ + if [ "$1" = "-fs" ]; then + filesystem="$2" + else + filesystem="$(get_filesystem "$1")" + fi + case $filesystem in + ext4|ext3|ext2|reiserfs|xfs|minix|hfs|efs|reiser4|jfs) echo Linux;; + iso9660) echo CD-ROM;; + vfat|ntfs) echo Windows;; + swap) echo Swap;; + *) echo "$filesystem";; + esac + # Other (not recognized) Filesystems: + # oracleasm, jbd, gfs, gfs2, vxfs, romfs, bfs, cramfs, + # qnx4, udf, ufs, hpfs, sysv, swsuspend, ocfs, ocfs2 +} + + diff --git a/backend/modules/partmgr b/backend/modules/partmgr new file mode 100644 index 0000000..c773e8d --- /dev/null +++ b/backend/modules/partmgr @@ -0,0 +1,24 @@ +#!/bin/bash + +function run_partmgr() +{ + case "$1" in + cfdisk|fdisk) + TERM=xterm /sbin/"$1" "$2" + ;; + gparted|qtparted) + "$1" "$2" + ;; + esac +} + +function send_partition_managers() +{ + send data partition_managers + for app in cfdisk gparted qtparted fdisk + do + which $app &>/dev/null || continue + echo $app + done +} + |