From fa22289c6fbd3abc1b4506553d55dcff20d619f1 Mon Sep 17 00:00:00 2001
From: Andreas Loibl <andreas@andreas-loibl.de>
Date: Tue, 27 Sep 2011 21:39:11 +0200
Subject: strip_live_media, error handling, hdmap fixes

---
 backend/modules/config     |  2 +-
 backend/modules/frontend   |  6 +++---
 backend/modules/hdmap      | 31 ++++++++++++-------------------
 backend/modules/partitions | 14 ++++++++++++++
 mainwizard.cpp             |  6 ++++++
 wizard/hdmap.cpp           | 23 ++++++++++++++++++++++-
 wizard/hdmap.h             |  2 ++
 wizard/rootpartition.cpp   | 29 ++++++++++++++++++++++++++++-
 wizard/rootpartition.h     |  3 +++
 9 files changed, 91 insertions(+), 25 deletions(-)

diff --git a/backend/modules/config b/backend/modules/config
index d073580..7fff7dd 100644
--- a/backend/modules/config
+++ b/backend/modules/config
@@ -42,7 +42,7 @@ function flag_unset()
 
 function hdmap_set()
 {
-	cfg_set hdmap "$( ( echo "$@"; ( echo "$@"; echo "$cfg_hdmap" ) | sort -u -t: -k1,1 ) | sort -u -t: -k2,2 | grep .)"
+	cfg_set hdmap "$( ( ( echo "$@"; ( echo "$@"; echo "$cfg_hdmap" ) | sort -u -t: -k1,1 ) | sort -u -t: -k2,2; awk -F: '{print $1":::"}' <<<"$@" ) | sort -u -t: -k1,1 | grep .)"
 }
 
 # Synopsis: hdmap_get <"device"|"mountpoint"|"filesystem"|"automount"> of <"device"|"mountpoint"> <device|mountpoint>
diff --git a/backend/modules/frontend b/backend/modules/frontend
index ffa2d28..8c6c87c 100644
--- a/backend/modules/frontend
+++ b/backend/modules/frontend
@@ -10,11 +10,11 @@ function send()
 function send_error()
 {
 	if [ "$#" -gt 1 ]; then
-		send error "$@" >&2
+		send error "$@"
 	elif [ "$#" -eq 1 ]; then
-		send error "$1" "$(tr -d '\n')" >&2
+		send error "$1" "$(tr -d '\n')"
 	else
-		send error 255 unknown >&2
+		send error 255 unknown
 	fi
 	return 1
 }
diff --git a/backend/modules/hdmap b/backend/modules/hdmap
index 220b5bd..50f1bc5 100644
--- a/backend/modules/hdmap
+++ b/backend/modules/hdmap
@@ -22,13 +22,6 @@ EOT
 }
 
 # FIXME TODO OLD OUTDATED 
-function emit_error()
-{
-send debug "$@"
-cat
-return 1
-}
-# FIXME TODO OLD OUTDATED 
 function emit_progress()
 {
         percent=$1
@@ -76,22 +69,22 @@ function handle_mountpoint_demands()
 		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
+				| send_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
+				| send_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
+				| send_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
+				| send_error 1
 				return 1
 			fi
 			;;
@@ -99,7 +92,7 @@ function handle_mountpoint_demands()
 			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
+			((A*B)) || ! ((A-B)) || ( echo ERROR: $PART "($POINT)" must $not be on a LVM-device! | send_error 1; return 1 ) || return 1
 			;;
 		esac
 		shift
@@ -157,14 +150,14 @@ function check_partitions_for_install()
 		
                 if [ "$device" = "$isosrc_dev" ]; then
                     if [ "$filesystem" ]; then
-                        emit_error 1 "Partition $device ($mountpoint) is mounted to /isosrc... This partition cannot be formatted!"
+                        send_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
+			[ "$automount" = "auto" ] || send_error 1 "Partition $device ($mountpoint) doesn't have the automount-flag set!" || return 1
 			eval handle_mountpoint_demands \"$device\" \"$filesystem\" $part_demands
 		fi
 		
@@ -174,14 +167,14 @@ function check_partitions_for_install()
 		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"
+			send_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
+		send_error 1 "No root-partition selected!"
 	fi
 }
 
@@ -296,7 +289,7 @@ function prepare_partitions_for_install()
 			if [ $RC -ne 0 ]; then
 				ERROR_MESSAGES=$(tail -8 $TMP)
 				echo "$ERROR_MESSAGES"
-				emit_error 1 "mkfs failed" || return 1
+				send_error 1 "mkfs failed" || return 1
 			fi
 	
 			# Deactivate dir_index-feature of ext2/ext3/ext4-partitions
@@ -325,12 +318,12 @@ function prepare_partitions_for_install()
 					fi
 					;;
 				*)
-					emit_error 1 "mount failed: $EC" || return 1
+					send_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
+				send_error 1 "mount failed: $EC" || return 1
 			fi
 		fi
 		
diff --git a/backend/modules/partitions b/backend/modules/partitions
index a42333e..211fdba 100644
--- a/backend/modules/partitions
+++ b/backend/modules/partitions
@@ -1,5 +1,15 @@
 #!/bin/bash
 
+# Synopsis: strip_live_media
+#
+# This function strips the live media (usbstick) from a list of devices
+# Output example:
+#   /dev/sda
+function strip_live_media()
+{
+	grep -ve '^$' $(awk '{if($2=="/live/image" && $3=="iso9660"){gsub(/[0-9]*$/,"",$1); print "-e ^"$1; exit 0;}}' < /proc/mounts)
+}
+
 # Synopsis: list_all_disks
 #
 # This function lists all disks
@@ -8,7 +18,9 @@
 #   /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
+    ) | strip_live_media
 }
 
 # Synopsis: send_list_of_disks
@@ -34,8 +46,10 @@ function send_list_of_disks()
 #   /dev/md0
 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
 	awk -vli="$(awk '{if($2=="md") print $1;}' /proc/devices)" 'BEGIN{m=split(li,list," ")}{for(i=1;i<=m;i++) if($1==list[i]) print "/dev/"$4;}' /proc/partitions
+    ) | strip_live_media
 }
 
 # Synopsis: list_dm_partitions
diff --git a/mainwizard.cpp b/mainwizard.cpp
index 61b14a1..bf4562b 100644
--- a/mainwizard.cpp
+++ b/mainwizard.cpp
@@ -80,6 +80,12 @@ void MainWizard::processCommand(QString command, QString args)
 	break;
       }
   }
+  else if(command == "error")
+  {
+    backendBusy(false);
+    QMessageBox::critical(0, tr("Backend Error"), tr("An error occurred:\n\n%1").arg(args)); 
+    backendBusy(true);
+  }
 }
 
 QSize MainWizard::sizeHint() const
diff --git a/wizard/hdmap.cpp b/wizard/hdmap.cpp
index 526ebef..491e5b6 100644
--- a/wizard/hdmap.cpp
+++ b/wizard/hdmap.cpp
@@ -8,8 +8,11 @@ wpHdMap::wpHdMap(QWidget *parent) : QWizardPage(parent)
   setupUi(this);
   backend = Backend::instance();
   connect(backend, SIGNAL(receivedDataLine(QString,QString)), this, SLOT(receivedDataLine(QString,QString)));
+  connect(backend, SIGNAL(receivedCommand(QString,QString)), this, SLOT(receivedCommand(QString,QString)));
   connect(backend, SIGNAL(finishedCommand(QString)), this, SLOT(backendFinishedCommand(QString)));
   tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
+
+  checkPassed = false;
 }
 
 void wpHdMap::initializePage()
@@ -39,6 +42,11 @@ void wpHdMap::receivedDataLine(QString data, QString line)
   }
 }
 
+void wpHdMap::receivedCommand(QString command, QString args)
+{
+  if(command == "error") checkPassed = false;
+}
+
 void wpHdMap::backendFinishedCommand(QString command)
 {
   if(command == "fill_hdmap")
@@ -65,6 +73,12 @@ void wpHdMap::backendFinishedCommand(QString command)
       if(hdmap.at(row).section(":",3,3) == "auto") automount->setChecked(true); else automount->setChecked(false);
       tableWidget->setCellWidget(row, 3, automount);
     }
+
+    checkPassed = false;
+  }
+  else if(command == "check_partitions_for_install" && checkPassed)
+  {
+    this->wizard()->next();
   }
 }
 
@@ -82,6 +96,11 @@ bool wpHdMap::isComplete() const
 bool wpHdMap::validatePage()
 {
   if(!isComplete()) return false;
+  if(checkPassed)
+  {
+    checkPassed = false;
+    return true;
+  }
   QStringList* hdmap = new QStringList();
   for(int row = 0; row < tableWidget->rowCount(); row++)
   {
@@ -93,5 +112,7 @@ bool wpHdMap::validatePage()
   }
   backend->cfg("hdmap", hdmap->join("\n"));
 //   backend->exec(QString("hdmap_set %1").arg(hdmap->join("\n")));
-  return true;
+  backend->exec("check_partitions_for_install");
+  checkPassed = true; // if an error occurrs receivedCommand will set it to false.
+  return false;
 }
diff --git a/wizard/hdmap.h b/wizard/hdmap.h
index 306266c..ec4ba5b 100644
--- a/wizard/hdmap.h
+++ b/wizard/hdmap.h
@@ -18,11 +18,13 @@ class wpHdMap : public QWizardPage, Ui::wpHdMap
   private:
     Backend* backend;
     QStringList filesystems;
+    bool checkPassed;
     
   private slots:
     void receivedDataLine(QString data, QString line);
     void updateComplete();
     void backendFinishedCommand(QString command);
+    void receivedCommand(QString command, QString args);
     
 };
 
diff --git a/wizard/rootpartition.cpp b/wizard/rootpartition.cpp
index dbecf43..b020370 100644
--- a/wizard/rootpartition.cpp
+++ b/wizard/rootpartition.cpp
@@ -11,6 +11,8 @@ wpRootPartition::wpRootPartition(QWidget *parent) : QWizardPage(parent)
   connect(backend, SIGNAL(receivedDataLine(QString,QString)), this, SLOT(receivedDataLine(QString,QString)));
   connect(rootPartitionDev, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(updateComplete()));
   connect(chkAdvanced, SIGNAL(stateChanged(int)), this, SLOT(updateComplete()));
+  
+  checkPassed = false;
 }
 
 void wpRootPartition::initializePage()
@@ -24,6 +26,8 @@ void wpRootPartition::clearPage()
   rootPartitionDev->clear();
   backend->exec("send_possible_root_filesystems");
   rootPartitionFs->clear();
+  
+  checkPassed = false;
 }
 
 void wpRootPartition::receivedDataLine(QString data, QString line)
@@ -50,15 +54,38 @@ bool wpRootPartition::isComplete() const
   return true;
 }
 
+void wpRootPartition::backendFinishedCommand(QString command)
+{
+  if(command == "check_partitions_for_install" && checkPassed)
+  {
+    this->wizard()->next();
+  }
+}
+
+void wpRootPartition::receivedCommand(QString command, QString args)
+{
+  if(command == "error") checkPassed = false;
+}
+
 bool wpRootPartition::validatePage()
 {
   if(!isComplete()) return false;
+  if(checkPassed)
+  {
+    checkPassed = false;
+    return true;
+  }
   if(rootPartitionDev->currentItem())
     backend->exec(QString("hdmap_set %1:/:%2:auto")
 	  .arg(rootPartitionDev->currentItem()->text().section(" ",0,0))
 	  .arg(chkFormat->isChecked() ? rootPartitionFs->currentText() : ""));
     backend->exec("fill_hdmap");
-  return true;
+  
+  if(chkAdvanced->isChecked()) return true;
+  
+  backend->exec("check_partitions_for_install");
+  checkPassed = true; // if an error occurrs receivedCommand will set it to false.
+  return false; 
 }
 
 int wpRootPartition::nextId() const
diff --git a/wizard/rootpartition.h b/wizard/rootpartition.h
index 393ec22..41b9df5 100644
--- a/wizard/rootpartition.h
+++ b/wizard/rootpartition.h
@@ -18,10 +18,13 @@ class wpRootPartition : public QWizardPage, Ui::wpRootPartition
     
   private:
     Backend* backend;
+    bool checkPassed;
     
   private slots:
     void receivedDataLine(QString data, QString line);
     void updateComplete();
+    void backendFinishedCommand(QString command);
+    void receivedCommand(QString command, QString args);
     
 };
 
-- 
cgit v1.0