From: ebelcrom Date: Sun, 2 Jun 2019 20:18:59 +0000 (+0200) Subject: sources added X-Git-Tag: v2.0~2 X-Git-Url: http://www.binomiant.duckdns.org/9wAuyR5S/?a=commitdiff_plain;h=27bc769753f5c982d14e84a00d8fad92b296dd72;p=rescuesys.git sources added --- diff --git a/.dialogrc b/.dialogrc new file mode 100644 index 0000000..d1d8f4a --- /dev/null +++ b/.dialogrc @@ -0,0 +1,144 @@ +# +# Run-time configuration file for dialog +# +# Automatically generated by "dialog --create-rc " +# +# +# Types of values: +# +# Number - +# String - "string" +# Boolean - +# Attribute - (foreground,background,highlight?) + +# Set aspect-ration. +aspect = 0 + +# Set separator (for multiple widgets output). +separate_widget = "" + +# Set tab-length (for textbox tab-conversion). +tab_len = 0 + +# Make tab-traversal for checklist, etc., include the list. +visit_items = OFF + +# Shadow dialog boxes? This also turns on color. +use_shadow = ON + +# Turn color support ON or OFF +use_colors = ON + +# Screen color +screen_color = (CYAN,BLUE,ON) + +# Shadow color +shadow_color = (BLACK,BLACK,ON) + +# Dialog box color +dialog_color = (BLACK,WHITE,OFF) + +# Dialog box title color +title_color = (BLUE,WHITE,ON) + +# Dialog box border color +border_color = (WHITE,WHITE,ON) + +# Active button color +button_active_color = (WHITE,BLUE,ON) + +# Inactive button color +button_inactive_color = dialog_color + +# Active button key color +button_key_active_color = button_active_color + +# Inactive button key color +button_key_inactive_color = (RED,WHITE,OFF) + +# Active button label color +button_label_active_color = (YELLOW,BLUE,ON) + +# Inactive button label color +button_label_inactive_color = (BLACK,WHITE,ON) + +# Input box color +inputbox_color = dialog_color + +# Input box border color +inputbox_border_color = dialog_color + +# Search box color +searchbox_color = dialog_color + +# Search box title color +searchbox_title_color = title_color + +# Search box border color +searchbox_border_color = border_color + +# File position indicator color +position_indicator_color = title_color + +# Menu box color +menubox_color = dialog_color + +# Menu box border color +menubox_border_color = border_color + +# Item color +item_color = dialog_color + +# Selected item color +item_selected_color = button_active_color + +# Tag color +tag_color = title_color + +# Selected tag color +tag_selected_color = button_label_active_color + +# Tag key color +tag_key_color = button_key_inactive_color + +# Selected tag key color +tag_key_selected_color = (RED,BLUE,ON) + +# Check box color +check_color = dialog_color + +# Selected check box color +check_selected_color = button_active_color + +# Up arrow color +uarrow_color = (GREEN,WHITE,ON) + +# Down arrow color +darrow_color = uarrow_color + +# Item help-text color +itemhelp_color = (WHITE,BLACK,OFF) + +# Active form text color +form_active_text_color = button_active_color + +# Form text color +form_text_color = (WHITE,CYAN,ON) + +# Readonly form item color +form_item_readonly_color = (BLUE,WHITE,ON) + +# Dialog box gauge color +gauge_color = title_color + +# Dialog box border2 color +border2_color = dialog_color + +# Input box border2 color +inputbox_border2_color = dialog_color + +# Search box border2 color +searchbox_border2_color = dialog_color + +# Menu box border2 color +menubox_border2_color = dialog_color diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..35407fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build.sh.log +mini.iso +rescuesys.img +rescuesys.vdi +setup.iso diff --git a/50-backup.rules b/50-backup.rules new file mode 100644 index 0000000..a9ab40d --- /dev/null +++ b/50-backup.rules @@ -0,0 +1 @@ +KERNEL=="sd[c-z]?", SUBSYSTEM=="block", ENV{ID_FS_LABEL}="RescueSys_Backup", SYMLINK+="backup", RUN+="/bin/bash -c 'echo backup > /home/rescuesys/fifo'" diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..d1a5519 --- /dev/null +++ b/build.sh @@ -0,0 +1,220 @@ +#!/bin/bash +# +# Shell script for building a RescueSys VM and image. Execution runs in this +# directory. +# + +LANG=C +SCRIPT=$(readlink -f $0) +exec 3>$SCRIPT.log +BASH_XTRACEFD=3 +set -e +set -x +cd $(dirname $SCRIPT) + +usage() +{ + cat << EOF +Shell script for building a RescueSys VM and image. +Usage: $0 [-h] [-g|-c|-r|-i] [-a] [-l] [-n] + +Options: -h show help (resp. this message) + -g generate setup.iso + -c create VM with VDI + -r run created VM + -i create raw image + -a all, run steps -g, -c, -r, -i + -l clean up vm + -n don't use ramfs +Some options are mutualy exclusive. +EOF +} + +generate_iso() +{ + echo "Installing p7zip-full, genisoimage..." + sudo apt-get -y install p7zip-full genisoimage &> /dev/null + + # mini.iso: check and get if not available + if ! [ -f mini.iso ]; then + echo "Downloading mini.iso..." + wget "http://archive.ubuntu.com/ubuntu/dists/bionic/main/installer-"` + `"amd64/current/images/netboot/mini.iso" > /dev/null + fi + + echo -n "Set host IP in preseed.cfg (press enter)... " + read + nano preseed.cfg + + echo "Generating setup.iso..." + + # unpack iso and initrd + local tmp_dir=$(mktemp -q -d /tmp/rescuesys_build.XXXXX) + 7z x -o$tmp_dir mini.iso > /dev/null + gunzip -q $tmp_dir/initrd.gz + + # add preseed and change boot timeout + echo -e 'preseed.cfg\nsetup\ngrub.png\nubuntu-logo.png\nubuntu-logo16.png'` + `'\ninitial\nrescuesys.sh\nhelp.txt\nwpa_supplicant.conf\n.dialogrc'` + `'\n50-backup.rules' |\ + cpio --quiet -F $tmp_dir/initrd --append -o -H newc + gzip -q $tmp_dir/initrd + sed 's/timeout.*$/timeout 1/g' -i $tmp_dir/isolinux.cfg + + # generate the new iso file + genisoimage -quiet -o setup.iso -r -J -no-emul-boot -boot-load-size 4\ + -boot-info-table -b isolinux.bin -c boot.cat $tmp_dir + rm -rf $tmp_dir +} + +create_VM() +{ + echo "Installing virtualbox..." + sudo apt-get -y install virtualbox > /dev/null + + echo "Creating VM with VDI in ramfs..." + + # create ramfs +# sudo mount -t ramfs ramfs -o mode=1777 ramfs +# cp setup.iso ramfs/ + + # create and configure VM + VBoxManage createvm --name rescuesys --register > /dev/null + VBoxManage modifyvm rescuesys --memory 1024 --acpi on --boot1 disk --boot2\ + dvd --vram 12 --cpus $(nproc) + VBoxManage modifyvm rescuesys --nic1 nat --nictype1 82540EM\ + --cableconnected1 on + VBoxManage modifyvm rescuesys --ostype Ubuntu_64 + VBoxManage modifyvm rescuesys --ioapic on +# VBoxManage createhd --filename ramfs/rescuesys.vdi --size 3814 > /dev/null + VBoxManage createhd --filename rescuesys.vdi --size 3814 > /dev/null + VBoxManage storagectl rescuesys --name SATA --add sata --hostiocache on +# VBoxManage storageattach rescuesys --storagectl SATA --port 0 --device 0\ +# --type hdd --medium ramfs/rescuesys.vdi +# VBoxManage storageattach rescuesys --storagectl SATA --port 1 --device 0\ +# --type dvddrive --medium ramfs/setup.iso + VBoxManage storageattach rescuesys --storagectl SATA --port 0 --device 0\ + --type hdd --medium rescuesys.vdi + VBoxManage storageattach rescuesys --storagectl SATA --port 1 --device 0\ + --type dvddrive --medium setup.iso +} + +run_VM() +{ + echo "Installing apt-cacher-ng..." + sudo apt-get -y install apt-cacher-ng > /dev/null + sudo /etc/init.d/apt-cacher-ng start > /dev/null + + echo "Running created VM..." + VBoxManage startvm rescuesys > /dev/null +} + +create_image() +{ + echo "Waiting on running rescuesys vm to finish..." + while true; do + local running=$(VBoxManage list runningvms | grep rescuesys) + if ! [ -z "$running" ]; then + sleep 1 + else + break + fi + done + + echo "Creating image..." + + rm -f rescuesys.img +# VBoxManage clonehd ramfs/rescuesys.vdi rescuesys.img --format RAW >\ +# /dev/null + VBoxManage clonehd rescuesys.vdi rescuesys.img --format RAW >\ + /dev/null + adapt_image +} + +adapt_image() +{ + echo "Adapt image (video and apt)..." + + set +e + sudo losetup -fP rescuesys.img + sudo mount /dev/loop0p1 mnt/ + sudo mount -o bind /dev mnt/dev + sudo mount -t proc proc mnt/proc + sudo mount -t sysfs sysfs mnt/sys + cat << EOF | sudo chroot mnt +set -e +sed 's/quiet video=1280x720/quiet/' -i /etc/default/grub +rm -f /etc/apt/apt.conf +update-grub2 +EOF + sudo umount mnt/sys + sudo umount mnt/proc + sudo umount mnt/dev + sudo umount mnt + sudo losetup -d /dev/loop0 + set -e +} + + +cleanup() +{ + echo "Cleaning up vm..." + + set +e + VBoxManage unregistervm rescuesys --delete &> /dev/null + rm -r ~/VirtualBox\ VMs/rescuesys &> /dev/null + sudo umount ramfs &> /dev/null + set -e +} + +action_other= +action_generate_iso= +action_create_VM= +action_run_VM= +action_create_image= +action_all= +action_cleanup= +option_noramfs= + +while getopts "hgcrialn" opt; do + case $opt in + h) + usage + exit 0 + ;; + g) + action_generate_iso=1 + action_other=1 + ;; + c) + action_create_VM=1 + action_other=1 + ;; + r) + action_run_VM=1 + action_other=1 + ;; + i) + action_create_image=1 + action_other=1 + ;; + a) + action_all=1 + ;; + l) + action_cleanup=1 + ;; + *) + usage + exit 1 + ;; + esac +done + +[ -z "$1" ] && { usage; exit 0; } + +if [ $action_all && $action_other ] || [ $action_cleanup && $action_other ] ||\ + [ $action_all && $action_cleanup ]; then + usage + exit 1 +fi diff --git a/grub.png b/grub.png new file mode 100644 index 0000000..5e550b0 Binary files /dev/null and b/grub.png differ diff --git a/help.txt b/help.txt new file mode 100644 index 0000000..ad7a00a --- /dev/null +++ b/help.txt @@ -0,0 +1,135 @@ +RescueSys v1.0 - Hilfe +====================== + +RescueSys kann Inhalte von Laufwerken eines Computers sichern und wiederher- +stellen. Das Backup der Daten wird auf einen Server im lokalen Netzwerk gespei- +chert und von diesem - nach Bedarf - wiederhergestellt. + +Steuerung +--------- + +Die Steuerung funktioniert komplett über die Tastatur (Pfeil-/Bildlauftasten, +Tabulator-, Space-, Enter-/Escape-Taste sowie F1). Um die Einträge in einem +Menü zu wechseln, muss die Pfeil-Oben-/Pfeil-Unten-Taste genutzt werden. Um +Dialoge zu bestätigen (OK, Weiter) oder abzulehnen (Abbrechen, Zurück) müssen +die Pfeil-Links-/-Rechts-Tasten zusammen mit Enter oder Escape genutzt werden. +Um Einträge aus- oder abzuwählen, drücken Sie die Leertaste. Für das Blättern +eines Textes in einem Dialog können die Pfeiltasten oder die Bildlauftasten +(Bild-Auf/Bild-Ab) genutzt werden. Für die Anzeige dieser Hilfe drücken Sie F1. + +In der Kopfzeile wird angezeigt, in wecher der nachfolgenden Funktionen man ist. + +Hauptmenü +--------- + +Das Hauptmenü ist in der Regel der erste Dialog den man sehen kann. Er führt zu +den Funktionen, die bei Auswahl aktiv werden. Nach Beendigung jeder Funktion, +kehrt man in der Regel zum Hauptmenü zurück. + +Funktion "Einstellungen" +------------------------ + +Gibt es noch keine Einstellungen, wird RescueSys Sie aufrufen, diese einzugeben. +Erfolgen falsche Eingaben, macht RescueSys Sie daruf aufmerksam. Gibt es bereits +aufgenommene Eingaben, erscheinen diese und müssen nur noch bestätigt werden. +Alle Einstellungen bleiben nach Beenden von RescueSys erhalten. + +Es gibt folgende Einstellungspunkte: + + - Benutzername: ist das der Name des Benutzers bzw. des Kontos im Windows Netz- + werk. Beispiel: mustermann.max + + - Passwort: ist das Passwort des Benutzers bzw. des Kontos im Windows Netzwerk. + Beachten Sie: das Passwort muss jedes mal eingegeben werden! + + - Netzlaufwerk: Pfad des Speicherortes im Windows Netzwerk. Er besteht aus + \\server\kompletter\pfad und kann statt des Servernamens auch eine IP-Adresse + enthalten. + + - Datenträger: Auswahl der zu sichernden Laufwerke des Computers. Die ausge- + wählten Laufwerke können auch inspiziert werden. Dabei wird eine Liste von + Details über das Laufwerk und seine Partitionen ausgegeben. + Beachten Sie: die Sicherung kann nur ganze Laufwerke enthalten! + + - Laufwerksbereinigung: diese Option führt in der Regel zu deutlich kleineren + Sicherungsdateien und einer Verringerung der Sicherungszeit. Da die Option + nicht ungefährlich ist, sollte + 1. ein Backup ohne die Option erfolgt sein + 2. der Computer nicht im Ruhezustand (Hibernation) sein. + ACHTUNG: die Option kann zu Datenverlust führen! + + - Autom. Herunterfahren: ist eine Sicherung oder Wiederherstellung erfolgt, + kann mit dieser Option der Computer automatisch ausgeschaltet werden. + +Funktion "Übersicht" +-------------------- + +Mit dieser Funktion können die Einstellungen angezeigt werden. Jeder Einstel- +lungspunkt wird mit seinem entsprechenden Wert angezeigt. Die Einstellungen +können hier nicht verändert werden. + +Funktion "Beenden" +------------------ + +Diese Funktion fährt den Computer herunter. + +Funktion "Sichern" +------------------ + +Mit "Sichern" führen Sie eine Sicherung der Laufwerke des Computers durch. Dabei +werden die Einstellungen benutzt, die vorher getätigt wurden. Um eine Sicherung +durchzuführen, muss der Sicherheitsdialog bestätigt werden. + +Je nach Einstellung erfolgt eine Bereinigung der Laufwerke, die Sicherung in +Backupdateien und eine Überprüfung dieser. + +Beachten Sie: von jedem eingestellten Laufwerk wird nur eine Sicherung +erstellt, d.h. ältere Sicherungen werden nach Erfolg dieser Funktion gelöscht. +Die Sicherung kann viele Stunden Zeit in Anspruch nehmen. Der Computer wird gem. +der Einstellungen ausgeschaltet. + +Funktion "Wiederherstellen" +--------------------------- + +Durch "Wiederherstellen" stellen Sie die Laufwerke aus der Sicherung wieder her. +Sie müssen die Laufwerke auswählen, die Sie wiederhergestellt haben wollen. Die +Auswahl zeigt den Laufwerknamen und den Zeitpunkt der Erstellung an. + +Nach einer erfolgreichen Wiederherstellung, werden die Partitionen des Laufwerke +für eine Überprüfung markiert. Das betrift die Partitionen mit dem Dateisystem +NTFS und EXT2/3/4. So werden diese beim Start des normalen Betriebssystems auto- +matisch überprüft. + +ACHTUNG: mit der Wiederherstellung werden die Daten der ausgewählten Laufwerke +unwiederbringlich überschrieben! + +Beachten Sie: die Wiederherstellung kann viele Minuten Zeit in Anspruch nehmen. +Der Computer wird gem. der Einstellungen ausgeschaltet. Es ist empfohlen, FAT- +-Partitionen manuell nach der Wiederherstellung zu überprüfen, da hierfür keine +automatische Überprüfung beim Start des normalen Betriebssystems eingerichtet +werden kann. + +Änderungshistorie +----------------- + +v1.0 Initiale Version + +Lizenz +------ + +RescueSys V1.0 - Ein System zum Sichern und Wiederherstellen von Laufwerken +Copyright (C) 2015 Dragan Isaković-Kutz + +Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU +General Public License, wie von der Free Software Foundation veröffentlicht, +weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder +(nach Ihrer Option) jeder späteren Version. + +Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von +Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite +Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. +Details finden Sie in der GNU General Public License. + +Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem +Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA. diff --git a/initial b/initial new file mode 100755 index 0000000..8a38999 --- /dev/null +++ b/initial @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Shell script finishes user resp. guest setup. Have a look in guest log if +# something goes wrong. +# + +SCRIPT=$(readlink -f $0) +LOG=$SCRIPT.log + +execute() +{ + echo "executing \"$1\"" >> $LOG + eval $1 >> $LOG 2>> $LOG || { + rm ~/.bash_profile &> /dev/null + sudo reboot &> /dev/null + } +} + +cleanup_and_exit() +{ + execute "sudo rm /usr/share/plymouth/plymouth-theme-ubuntu-logo*" + execute "echo 'sudo setupcon -f &> /dev/null && ./rescuesys.sh' >"` + `" ~/.bash_profile" + execute "rm $SCRIPT" + sudo reboot &> /dev/null +} + +# show a nice dialog message +dialog --colors --infobox "\n\n\Zb\Z1"` + `" FINISHING USER SETUP"` + `"\n\n\ZnPlease stand by while user setup is finishing..." 10 30 + +execute "sudo dpkg -i $(ls /usr/share/plymouth/plymouth-theme-ubuntu-logo*)" +execute "sudo cp /usr/share/plymouth/ubuntu-logo.png /usr/share/plymouth/"` + `"themes/ubuntu-logo/" +execute "sudo cp /usr/share/plymouth/ubuntu-logo16.png /usr/share/plymouth/"` + `"themes/ubuntu-logo/" +execute "sudo sed -e 's/Window.SetBackgroundTopColor.*/"` + `"Window.SetBackgroundTopColor (0.00, 0.44, 0.72);/' "` + `"-e 's/Window.SetBackgroundBottomColor.*/"` + `"Window.SetBackgroundBottomColor (0.00, 0.44, 0.72);/' "` + `"-i /usr/share/plymouth/themes/ubuntu-logo/ubuntu-logo.script" +execute "sudo sed -e 's/FONTFACE=.*/FONTFACE=\"Terminus\"/' "` + `"-e 's/FONTSIZE=.*/FONTSIZE=\"10x20\"/' "` + `"-i /etc/default/console-setup" +execute "sudo update-initramfs -u -k all" +execute "touch ~/.hushlogin" +execute "mkfifo -m 644 ~/fifo" + +cleanup_and_exit diff --git a/preseed.cfg b/preseed.cfg new file mode 100644 index 0000000..927ad04 --- /dev/null +++ b/preseed.cfg @@ -0,0 +1,96 @@ +# regional setting +d-i debian-installer/language string en_US:en +d-i debian-installer/country string US +d-i debian-installer/locale string en_US +d-i debian-installer/splash boolean true +d-i localechooser/supported-locales multiselect en_US.UTF-8 +d-i pkgsel/install-language-support boolean true + +# keyboard selection +d-i console-setup/ask_detect boolean false +d-i keyboard-configuration/modelcode string pc105 +d-i keyboard-configuration/layoutcode string de +d-i keyboard-configuration/variantcode string +d-i keyboard-configuration/xkb-keymap select de +d-i debconf/language string en_US:en + +# network settings +d-i netcfg/choose_interface select auto +d-i netcfg/dhcp_timeout string 5 +d-i netcfg/hostname string rescuesys +d-i netcfg/get_hostname string rescuesys +d-i netcfg/get_domain string local + +# mirror settings +d-i mirror/country string manual +d-i mirror/http/hostname string de.archive.ubuntu.com +d-i mirror/http/directory string /ubuntu +#d-i mirror/http/proxy string http://192.168.0.180:3142 +d-i mirror/http/proxy string http://192.168.2.28:3142 + +# clock and timezone settings +d-i time/zone string Europe/Berlin +d-i clock-setup/utc boolean true +d-i clock-setup/ntp boolean false + +# user account setup +d-i passwd/root-login boolean true +d-i passwd/root-password-crypted password $6$xD6F.QDNwY$/s34q1eJuDVuNSBJhx6k8/s82fjvhJ8z6p9VubLU7zHwWI3NrYWz1Gz0j6X8BslupYAg8rXYVHKZZLBGJblvR0 +d-i passwd/make-user boolean true +d-i passwd/user-fullname string rescuesys +d-i passwd/username string rescuesys +d-i passwd/user-password-crypted password $6$qZ8kIO.2QDb0avLy$1BifKPVdA3qHbod4QSFsXZKt.MN7vuZkxdDOSNiwop0DWOU0Miw4kx67bJMSJKt.9VrdgQIgReemwjEQTaPxv. +#d-i passwd/user-uid string +d-i user-setup/allow-password-weak boolean true +d-i passwd/user-default-groups string cdrom dialout lpadmin plugdev sambashare sudo +d-i user-setup/encrypt-home boolean false + +# configure apt +d-i apt-setup/restricted boolean true +d-i apt-setup/universe boolean true +d-i apt-setup/backports boolean true +d-i apt-setup/services-select multiselect security +d-i apt-setup/security_host string security.ubuntu.com +d-i apt-setup/security_path string /ubuntu +tasksel tasksel/first multiselect standard +d-i pkgsel/include string dialog, mc, screen, cifs-utils, net-tools,\ + ifupdown, wireless-tools, wpasupplicant, plymouth-theme-ubuntu-logo,\ + p7zip-full, pv, zerofree, bmon, htop +d-i pkgsel/upgrade select safe-upgrade +d-i pkgsel/update-policy select unattended-upgrades +d-i pkgsel/updatedb boolean true + +# disk partitioning +d-i partman-auto/method string regular +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-md/device_remove_md boolean true +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true +d-i partman-auto/expert_recipe string \ + boot-root :: \ + 1 1 1000000000 ext4 \ + $primary{ } $bootable{ } \ + method{ format } format{ ext4 } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . +d-i partman-swapfile/percentage string 0 +d-i partman-swapfile/size string 0 +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Do any late command +d-i preseed/late_command string /setup + +# grub boot loader +d-i grub-installer/only_debian boolean true +d-i grub-installer/with_other_os boolean true + +# finish installation +d-i finish-install/reboot_in_progress note +d-i finish-install/keep-consoles boolean false +d-i cdrom-detect/eject boolean true +d-i debian-installer/exit/halt boolean false +d-i debian-installer/exit/poweroff boolean false diff --git a/rescuesys.sh b/rescuesys.sh new file mode 100755 index 0000000..6812afe --- /dev/null +++ b/rescuesys.sh @@ -0,0 +1,1150 @@ +#!/bin/bash +# +# Main RescueSys shell script. +# + +LOGFILE=/tmp/rescuesys.log +exec 3>$LOGFILE +BASH_XTRACEFD=3 +set -x + +# constants +DIALOG_OK=0 +DIALOG_CANCEL=1 +DIALOG_HELP=2 +DIALOG_EXTRA=3 +DIALOG_ITEM_HELP=4 +DIALOG_ERROR=-1 +SETTINGS_DONE=0 +OUT=/tmp/output_file +PROGRESS_FILE=/tmp/progress +MNT_DIR=/mnt +SETTINGS_FILE=$HOME/rescuesys.settings +INSP_DIR=$HOME/mnt +ERROR_FILE=/tmp/error +FIFO=$HOME/fifo +USB_PART=/dev/backup + +# variables +mode="" +user="" +interface="" +pass="" +domain="" +store_path="" +backup_choice="" +cleanup="" +auto_down="" + +# welcome dialog: shows first message to the user +welcome() +{ + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü " --title " Willkommen " --colors --ok-label "Weiter"\ + --hfile help.txt --exit-label "Schließen" --msgbox "\nRescueSys hat entdeckt, dass Sie noch nie eine Sicherung"` + `" durchgeführt haben. Daher müssen Sie zunächst notwendige Einstellungen vornehmen.\n\nDiese Daten werden gespeichert"` + `" und beim nächsten Start von RescueSys benutzt." 12 60 +} + +# backup/restore dialog: input mask for backup/restore mode +br_mode() +{ + # preset dialog + local usb_switch=off + local net_switch=on + if [ "$mode" = "USB" ]; then + usb_switch=on + net_switch=off + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Modus "\ + --hfile help.txt --colors --nocancel --ok-label "Weiter" --radiolist "Im welchen Modus wollen Sie die Sicherung und"` + `" Wiederherstellung vornehmen?" 10 60 2\ + USB "USB-Laufwerk" $usb_switch\ + Netzwerk "Netzlaufwerk" $net_switch 2>$OUT + + mode="$(cat $OUT)" +} + +# USB drive dialog: waits on plugging in USB drive and confirmation +detect_drive() +{ + # flush data in fifo + dd if=$FIFO iflag=nonblock &> /dev/null + + # show 1st dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --title " USB-Laufwerk "\ + --hfile help.txt --colors --nocancel --nook --infobox "Stecken Sie das USB-Laufwerk, auf dem die Sicherung erfolgen"` + `" soll, jetzt ein.\n\nIst das Laufwerk schon eingesteckt, dann entfernen Sie es und stecken es wieder ein." 8 50 + + # wait on udev message + cat $FIFO &> /dev/null + + # mount USB drive + sudo mount -o ro $USB_PART $INSP_DIR &> /dev/null + # TODO: error handling + + # examine USB drive + local size=$(lsblk -nl $USB_PART | sed 's/\ */ /g' | cut -f 4 -d ' ') + local free=$(df -h | grep $INSP_DIR | sed 's/\ */ /g' | cut -f 4 -d ' ') + local text="Soll Laufwerk\n\n $USB_PART (1. Partition)\n Größe $size, frei $free\n\nverwendet werden?" + + # umount USB drive + sudo umount $INSP_DIR &> /dev/null + + # show 2nd dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " USB-Laufwerk "\ + --hfile help.txt --colors --yes-label "Ja" --no-label "Nein" --yesno "$text" 10 40 2>$OUT + + # examine result + local resp=$? + case $resp in + $DIALOG_OK) + return 0 + ;; + *) + return 1 + ;; + esac +} + +# username dialog: input mask for username +username() +{ + # preset dialog + local init="" + if ! [ "$user" = "" ]; then + init="$user" + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Benutzername "\ + --hfile help.txt --colors --nocancel --ok-label "Weiter" --inputbox "Geben Sie ihren Benutzernamen ein (falls leer"` + `" wird \"guest\" verwendet):" 9 50 $init 2>$OUT + + user="$(cat $OUT)" + if [ -z $user ]; then + user="guest" + fi +} + +# password dialog: input mask for password +password() +{ + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Passwort "\ + --hfile help.txt --colors --nocancel --insecure --ok-label "Weiter" --passwordbox "Geben Sie ihr Passwort ein (falls"` + `" leer wird \"guest\" verwendet):" 9 50 2>$OUT + + pass="$(cat $OUT)" + if [ -z $pass ]; then + pass="guest" + fi +} + +# domain dialog: input mask for domain +dom() +{ + # preset dialog + local init="" + if ! [ "$domain" = "" ]; then + init="$domain" + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Domäne "\ + --hfile help.txt --colors --nocancel --ok-label "Weiter" --inputbox "Geben Sie den Domänennamen ein (falls leer wird"` + `" \"workgroup\" verwendet):" 9 50 $init 2>$OUT + + domain="$(cat $OUT)" + if [ -z $domain ]; then + domain="workgroup" + fi +} + +# interface dialog +interface() +{ + # find devices + local IFS_saved=$IFS; + IFS=$'\n' + local devs=($(cat /proc/net/dev | grep -F ':' | tr -d ' ' | sed 's/:.*//g')) + IFS=$IFS_saved + local list=( ) + + # remove lo interface from array + for i in $(seq 0 $((${#devs[@]}-1))); do + if [ "${devs[$i]}" = "lo" ]; then + unset devs[$i] + else + list=(${list[@]} ${devs[$i]} ${devs[$i]} on) + fi + done + + # show dialog + eval dialog --backtitle "\"RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen\"" --title "\" Netzwerkgerät \""\ + --hfile help.txt --colors --nocancel --ok-label "Weiter" --radiolist "\"Welches Netzwerkgerät soll verwendet werden?\""\ + 10 50 5 ${list[@]} 2>$OUT + + interface="$(cat $OUT)" + + local type= + case $(cat /sys/class/net/$interface/type) in + 1) + if [ -d /sys/class/net/$interface/wireless ] || [ -L /sys/class/net/$interface/phy80211 ]; then + type=wlan + else + type=lan + fi + ;; + *) + echo "TODO: kein eth Netzwerkgerät gefunden" + read + ;; + esac + + # switch off all interfaces + sudo ifdown -a &>/dev/null + + # enter interface in /etc/network/interfaces + cat < /tmp/interfaces +# Created by rescuesys.sh + +auto lo +iface lo inet loopback + +auto $interface +iface $interface inet dhcp +EOF + + # handle a wireless interface by showing a dialog... + if [ "$type" = "wlan" ]; then + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " WPA Einstellungen "\ + --hfile help.txt --colors --nocancel --ok-label "Weiter" --form "Tragen Sie die Zugangsdaten ihres WPA/WPA2"` + `" Netzwerks ein:" 11 50 3\ + "Name (SSID):" 1 1 "" 1 18 26 0\ + "Schlüssel (PSK):" 2 1 "" 2 18 26 0\ + "IP-Adresse:" 3 1 "(über DHCP)" 3 18 0 26 2>$OUT + + # reading the settings... + local -a wlan_settings + while read -r line; do + wlan_settings=(${wlan_settings[@]} $line) + done < $OUT + + # writing wpa_supplicant.conf... + sudo sed -e "s/\tssid=.*/\tssid=\"${wlan_settings[0]}\"/" -e "s/psk=.*/psk=\"${wlan_settings[1]}\"/"\ + -i /etc/wpa_supplicant/wpa_supplicant.conf &> /dev/null + + # and writing interfaces + echo -e "\twpa-conf /etc/wpa_supplicant/wpa_supplicant.conf" >> /tmp/interfaces + fi + + sudo bash -c "cat /tmp/interfaces > /etc/network/interfaces" + rm /tmp/interfaces + + # switch on all interfaces + sudo ifup -a &>/dev/null +} + +# shutdown option dialog: sets shutdown as option for a backup process +shutdown_option() +{ + # preset dialog + local init=yes + if [ "$auto_down" = "nein" ]; then + init=no + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Automatisches Herunterfahren "\ + --colors --yes-label "Ja" --no-label "Nein" --hfile help.txt --exit-label "Schließen" --default-button $init\ + --yesno "\nSoll der Computer nach einer Sicherung oder Wiederhestellung automatisch heruntergefahren werden?"\ + 9 40 2>$OUT + + # examine result + local resp=$? + case $resp in + $DIALOG_OK) + auto_down="ja" + ;; + $DIALOG_CANCEL) + auto_down="nein" + ;; + *) + auto_down="nein" + ;; + esac + + # store settings + save_settings +} + +# cleanup dialog: sets the cleanup method for file systems (zerofree etc.) +cleanup_method() +{ + # preset dialog + local init=no + if [ "$cleanup" = "ja" ]; then + init=yes + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Laufwerksbereinigung "\ + --colors --yes-label "Ja" --no-label "Nein" --hfile help.txt --exit-label "Schließen" --default-button $init\ + --yesno "\nSoll vor einer Sicherung das Laufwerk bereinigt werden, so das die Sicherungsdatei so klein wie möglich"` + `" ausfällt?\n\Z1ACHTUNG: Bei der Wahl dieser Option kann das Laufwerk beschädigt werden, falls des Computer im"` + `" Ruhezustand ist!\Zn\nEs ist empfohlen, ein Backup ohne diese Option zu erstellen und erst dann eines mit."\ + 14 60 2>$OUT + + # examine result + local resp=$? + case $resp in + $DIALOG_OK) + cleanup="ja" + ;; + $DIALOG_CANCEL) + cleanup="nein" + ;; + *) + cleanup="nein" + ;; + esac + + # store settings + save_settings +} + +# mounts store/network drive +mount_store() +{ + if [ "$mode" == "USB" ]; then + # detect drive + detect_drive + if [ $? -ne 0 ]; then + return 1; + fi + # mount USB drive + sudo mount $store_path $MNT_DIR &> /dev/null + else + # mount network drive + sudo mount -t cifs $(echo $store_path | sed 's/\\/\//g') $MNT_DIR -o\ + "username=$user,password=$pass,domain=$domain,vers=1.0" &> /dev/null + fi + + return $? +} + +# unmount store/network drive +unmount_store() +{ + sudo umount $MNT_DIR &>/dev/null +} + +# no store dialog: error dialog for unmountable network drive +no_store() +{ + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Fehler " --hfile help.txt\ + --colors --ok-label "Abbrechen" --exit-label "Schließen" --msgbox "\nLaufwerk konnte nicht eingebunden werden."` + `" Bitte Einstellungen überprüfen und erneut versuchen." 9 50 +} + +# store dialog: input mask for network drive +# param 1 is the init mode, setting a value turns it on, off otherwise +# returns 0 if , 1 otherwise +store() +{ + # prepare mode handling + local init="" + if [ -z $1 ]; then + init="$store_path" + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Netzlaufwerk "\ + --hfile help.txt --colors --nocancel --ok-label "Weiter" --exit-label "Schließen" --inputbox "Geben Sie den Pfad"` + `" komplett an:\n(\\\\server\\kompletter\\pfad)" 9 60 $init 2>$OUT + + # test network drive + store_path="$(cat $OUT)" + mount_store + local res=$? + unmount_store + + return $res +} + +# inspect dialog: shows disk and partition details +# returns 0 if username is not empty, 1 otherwise +inspect() +{ + # string template for inspect file + local disk_text="Datenträger: #disk#\n \x20Größe: #size#\n \x20Partitionen: #parts#\n" + local part_text="\nPartition: #part#\n \x20Größe: #psize#\n \x20Belegt: #used#\n \x20Dateisystem: #fstype#\n"` + `" \x20Bezeichnung: #label#\n \x20Inhalt (Dateien, Verzeichnisse/):\n" + + # fill inspect file with information + rm -f /tmp/inspect_file &>/dev/null + for disk in $backup_choice; do + # write template to file + echo -en $disk_text >> /tmp/inspect_file + + # replace placeholder for disk name + sed -i "s/#disk#/$disk/" /tmp/inspect_file + + # replace placeholder for disk size + local size=$(lsblk -nl -o NAME,SIZE | grep "$disk\W" | sed 's/\ */ /g' | cut -f 2 -d ' ') + sed -i "s/#size#/$size/" /tmp/inspect_file + + # determine partition names and replace placeholder + local parts=$(ls /dev/${disk}* | grep "$disk\w") + parts="$(echo $parts | sed -e 's/\ /\\\ /g' -e 's/\/dev\///g')" + sed -i "s/#parts#/$parts/" /tmp/inspect_file + + # fill partition details + for part in $parts; do + # write template to file + echo -en $part_text >> /tmp/inspect_file + + # replace placeholder for partition name + part="$(echo $part | sed -e 's/\\//g')" + sed -i "s/#part#/$part/" /tmp/inspect_file + + # replace placeholder for partition size + local psize=$(lsblk -nl -o NAME,SIZE | grep "$part" | sed 's/\ */ /g' | cut -f 2 -d ' ') + sed -i "s/#psize#/$psize/" /tmp/inspect_file + + # replace placeholder for partition type + local fstype=$(sudo lsblk -nl -o NAME,FSTYPE | grep "$part" | sed 's/\ */ /g' | cut -f 2 -d ' ') + sed -i "s/#fstype#/$fstype/" /tmp/inspect_file + + # replace placeholder for partition label + local label="(keine)" + local lname="" + case $fstype in + vfat) + lname=$(sudo mlabel -i /dev/$part -s ::) + if [ " Volume has no label" = "$lname" ] + then + : + else + label="$(echo $lname | cut -f 4 -d ' ')" + fi + ;; + ntfs) + lname=$(sudo ntfslabel /dev/$part) + if ! [ -z $lname ]; then + label="$(echo $lname)" + fi + ;; + ext*) + lname=$(sudo tune2fs -l /dev/$part | grep "volume name" | sed "s/\ */ /g" | cut -f 4 -d ' ') + if ! [ "" = "$lname" ]; then + label="$(echo $lname)" + fi + ;; + esac + sed -i "s/#label#/$label/" /tmp/inspect_file + + # mount partition for content inspection + sudo mount -o ro /dev/$part $INSP_DIR &>/dev/null + # TODO: error handling + + # replace placeholder for partition usage + local used="$(df -h | grep $part | sed 's/\ */ /g' | cut -f 4,5 -d ' ')" + sed -i "s/#used#/$used/" /tmp/inspect_file + + # determine partition content + local IFS_saved=$IFS; + IFS=$'\n' + local entries=($(ls -F $INSP_DIR)) + IFS=$IFS_saved + + # write each entry to inspection file + for i in $(seq 0 $((${#entries[@]}-1))); do + echo " ${entries[$i]}" >> /tmp/inspect_file + done + + # unmount partition + sudo umount $INSP_DIR &>/dev/null + done + echo "" >> /tmp/inspect_file + done + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen / Inspizieren" --hfile help.txt\ + --title " Datenträgerdetails " --exit-label "Schließen" --colors --nocancel --exit-label "Zurück"\ + --textbox /tmp/inspect_file 23 60 +} + +# disk choose dialog: lists disks, also for inspection +# returns 0 if username is not empty, 1 otherwise +choose() +{ + # look for disks + local disks=($(lsblk -nl -o NAME,TYPE,SIZE | grep disk | sort | sed 's/\ */ /g' | cut -f 1 -d ' ')) + local sizes=($(lsblk -nl -o NAME,TYPE,SIZE | grep disk | sort | sed 's/\ */ /g' | cut -f 3 -d ' ')) + local mount_dev=$(mount | grep 'on / '| cut -f 1 -d ' ') + local own_disk=$(echo ${mount_dev##*/} | sed 's/[0-9]*$//') + local usb_disk=$(echo ${usb_real_name##*/} | sed 's/[0-9]*$//') + + while true; do + unset entries + declare -a entries + # prepare dialog entries + local i=0 + for disk in ${disks[@]}; do + # look for checked entries + local checked=off + if ! [ -z "$(echo $backup_choice | grep $disk)" ]; then + checked=on + fi + # exclude own disk and USB drive + if [ "$disk" = "$own_disk" ] || [ "$disk" = "$usb_disk" ]; then + : + else + local parts=$(ls /dev/${disk}* | wc -l) + let 'parts=parts-1' + local entries=(${entries[@]} "$disk \"Größe: ${sizes[$i]}, Partitionen: $parts\" $checked") + fi + let "i=i+1" + done + + # show dialog + eval dialog --backtitle "\"RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen\"" --exit-label "Schließen"\ + --title "\" Datenträger \"" --hfile help.txt --colors --nocancel --ok-label "Weiter"\ + --extra-button --extra-label "Inspizieren" --checklist "\"Wählen Sie einen oder mehrere Datenträger aus, die Sie"` + `" sichern wollen - ausgewählte Datenträger können vorher inspiziert werden:\"" 14 50 4 ${entries[@]} 2>$OUT + + # save choice result + local res=$? + backup_choice="$(cat $OUT)" + if [ -z "$backup_choice" ]; then + # show error + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Einstellungen" --title " Fehler "\ + --colors --ok-label "Weiter" --hfile help.txt --exit-label "Schließen" --msgbox "\nBitte wählen Sie"` + `" mindestens ein Laufwerk aus." 8 40 + + # show dialog again + continue + fi + + # inspect disk if needed + if [ $res -eq $DIALOG_EXTRA ]; then + inspect wizz + + # show dialog again + continue + fi + + # end loop + break + done +} + +# keeps only recent backups +# param 1 is the time duration of backup +clean_backup() +{ + # read config + local config_file=backup_$user.conf + local IFS_saved=$IFS + IFS=$'\n' + local entries=($(sudo cat $MNT_DIR/$config_file | sort | sed 's/=.*//g' | uniq -c | sed -e '' -e 's/\ */ /g')) + IFS=$IFS_saved + + # process each entry + for i in $(seq 0 $((${#entries[@]}-1))); do + if [ $(echo ${entries[$i]} | cut -f 1 -d ' ') -eq 2 ]; then + local disk=$(echo ${entries[$i]} | cut -f 2 -d ' ') + local del_line=$(sudo cat $MNT_DIR/$config_file | grep $disk | head -n 1) + + # edit config + sudo sed -i "/$del_line/d" $MNT_DIR/$config_file + # remove file + sudo rm -f $MNT_DIR/$(echo $del_line | sed 's/.*=//g') + fi + done + + # save duration at least + local duration="$(sudo grep duration $MNT_DIR/$config_file)" + if [ -z $duration ]; then + sudo bash -c "echo \"duration=$(($1/3600))h$((($1%3600)/60))m$(($1%60))s\" >> $MNT_DIR/$config_file" + else + sudo sed -i "/$duration/d" $MNT_DIR/$config_file + sudo bash -c "echo \"duration=$(($1/3600))h$((($1%3600)/60))m$(($1%60))s\" >> $MNT_DIR/$config_file" + fi +} + +# cleans up a ext filesystem for better compression and shows busy state +# param 1 is the current partition +# param 2 is the amount of all partition for cleaning up +# param 3 is the partition name +ext_cleanup() +{ + local progress=$((($1-1)*100/$2)) + echo $progress | dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --colors\ + --title " Bereinigung $1/$2 " --hfile help.txt --exit-label "Schließen" --gauge "\nBereinigung der EXT2/3/4 Partition"` + `" $3 läuft..." 8 56 + + # SSD? + if [ $(cat /sys/block/${3%3}/queue/rotational) ]; then + # mount and use fstrim + sudo mount -o ro /dev/$3 $INSP_DIR &>/dev/null + sudo fstrim $INSP_DIR &>/dev/null + sudo umount $INSP_DIR &>/dev/null + else + # zerofree partition + sudo zerofree /dev/$3 &>/dev/null + fi + sync &>/dev/null +} + +# cleans up a ntfs filesystem for better compression and shows busy state +# param 1 is the current partition +# param 2 is the amount of all partition for cleaning up +# param 3 is the partition name +vfat_cleanup() +{ + local progress=$((($1-1)*100/$2)) + echo $progress | dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --colors\ + --title " Bereinigung $1/$2 " --hfile help.txt --exit-label "Schließen" --gauge "\nBereinigung der FAT Partition $3"` + `" läuft..." 8 56 + + # mount fs + sudo mount /dev/$3 $MNT_DIR &>/dev/null || return 1 + + # fill fs with n * 4GiB files and delete them + while true; do + sudo dd if=/dev/zero of=$MNT_DIR/zero_$(date +%s).tmp bs=512 count=8388607 &>/dev/null || break + done + sync &>/dev/null + sudo rm -f $MNT_DIR/zero_*.tmp + sync &>/dev/null + + # unmount fs + sudo umount $MNT_DIR &>/dev/null +} + +# cleans up a ntfs filesystem for better compression while showing busy state +# param 1 is the current partition +# param 2 is the amount of all partition for cleaning up +# param 3 is the partition name +ntfs_cleanup() +{ + local progress=$((($1-1)*100/$2)) + echo $progress | dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --colors\ + --title " Bereinigung $1/$2 " --hfile help.txt --exit-label "Schließen" --gauge "\nBereinigung der NTFS Partition"` + `" $3 läuft..." 8 56 + + # ntfswipe partition + sudo ntfswipe -a /dev/$3 &>/dev/null + sudo ntfsfix /dev/$3 &>/dev/null + sync &>/dev/null +} + +# wipes out unneccessary data from file system for better compression +wipeout() +{ + local pcount=0 + local curr_part=0 + + # count partitions, process each disk + for disk in $backup_choice; do + local parts=$(ls /dev/${disk}* | grep "$disk\w") + parts="$(echo $parts | sed 's/\/dev\///g')" + + # process each partition + for part in $parts; do + local fstype=$(sudo lsblk -nl -o NAME,FSTYPE | grep "$part" | sed 's/\ */ /g' | cut -f 2 -d ' ') + case $fstype in + vfat) + let 'pcount=pcount+1' + ;; + ntfs) + let 'pcount=pcount+1' + ;; + ext*) + let 'pcount=pcount+1' + ;; + esac + done + done + + # wipe out, process each disk + for disk in $backup_choice; do + local parts=$(ls /dev/${disk}* | grep "$disk\w") + parts="$(echo $parts | sed 's/\/dev\///g')" + + # process each partition + for part in $parts; do + local fstype=$(sudo lsblk -nl -o NAME,FSTYPE | grep "$part" | sed 's/\ */ /g' | cut -f 2 -d ' ') + case $fstype in + vfat) + let 'curr_part=curr_part+1' + vfat_cleanup $curr_part $pcount $part + ;; + ntfs) + let 'curr_part=curr_part+1' + ntfs_cleanup $curr_part $pcount $part + ;; + ext*) + let 'curr_part=curr_part+1' + ext_cleanup $curr_part $pcount $part + ;; + esac + done + done +} + +# backup dialog: does disk backup with a progress indication +backup() +{ + # confirm action + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --title " Sicherung bestätigen "\ + --hfile help.txt --colors --yes-label "Weiter" --no-label "Abbrechen" --exit-label "Schließen" --yesno "\nWollen Sie"` + `" das/die Laufwerk/e \Z4${backup_choice}\Zn nach \Z4${store_path}\Zn sichern?" 9 50 2>$OUT + + if ! [ $? -eq $DIALOG_OK ]; then + return + fi + + # wipe out unneccessary data + if [ $cleanup = "ja" ]; then + wipeout + fi + + # mount store + mount_store + if [ $? -ne 0 ]; then + # show error + no_store + + return + fi + + # process each disk + echo -n "" > $ERROR_FILE + i=1 + count=$(echo $backup_choice | wc -w) + local start_ts=$(date +"%s") + for disk in $backup_choice; do + # set size and name + local psize=$(($(sudo fdisk -l 2>/dev/null | grep "${disk}:" | cut -f 5 -d ' ')/1024)) + local arch_name="backup_$(date +%Y-%m-%d_%H-%M-%S).img" + + # start compression process + local dd_opts="bs=512 conv=noerror,sync" + echo -n "" > $PROGRESS_FILE &>/dev/null + (sudo dd if=/dev/$disk $dd_opts 2>/dev/null | pv -s ${psize}k -n 2>$PROGRESS_FILE | sudo 7zr a -t7z -m0=lzma2 -mx=9\ + -mfb=64 -md=32m -ms=on -bd -si $MNT_DIR/$arch_name 2>/dev/null | : | tail -fn0 $PROGRESS_FILE 2>>/dev/null |\ + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --colors\ + --title " Sicherung $i/$count " --hfile help.txt --exit-label "Schließen" --gauge "Sicherung von \Z4${disk}\Zn als"` + `" \Z4${store_path}\\$arch_name\Zn" 8 60)& + + # supervise compression process + sleep 2 + while true; do + sleep 1 + local run=$(ps -e | grep 7zr) + + if [ -z "$run" ]; then + killall tail &>/dev/null + rm -f $PROGRESS_FILE &>/dev/null + break + fi + done + let 'i=i+1' + + # test archive + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --title " Überprüfung " --hfile help.txt\ + --colors --exit-label "Schließen" --infobox "Backupdatei \Z4${store_path}\\$arch_name\Zn wird überprüft..." 7 60\ + 2>$OUT + + sudo 7zr t $MNT_DIR/$arch_name &>/dev/null + if [ $? -ne 0 ]; then + # show error messages + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Sichern" --title " Fehler " --colors\ + --hfile help.txt --exit-label "Schließen" --msgbox "\nBei der Erstellung der Sicherung von \Z4${disk}\Zn als"` + `" \Z4${store_path}\\$arch_name\Zn ist ein Fehler aufgetreten. Das Archiv ist ungültig und wird gelöscht. Die"` + `" Sicherung wird abgebrochen." 12 50 + + # delete backup + rm -f $MNT_DIR/$arch_name &>/dev/null + + # unmount store + unmount_store + + return + fi + + # create config entry + local config_file=backup_$user.conf + sudo bash -c "echo \"$disk=$arch_name\" >> $MNT_DIR/$config_file 2>>$ERROR_FILE" + done + unset i + unset count + + # just keep recent update + local end_ts=$(date +"%s") + local diff=$(($end_ts-$start_ts)) + clean_backup $diff + + # unmount store + unmount_store + + # shutdown? + if [ "$auto_down" = "ja" ]; then + shutdown_computer + fi +} + +# mark dialog: marks partition for checking and shows busy state +# param 1 is the list of disks that have been restored +mark4check() +{ + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Wiederherstellen" --title " Überprüfung " --hfile help.txt\ + --colors --exit-label "Schließen" --infobox "Laufwerke werden für eine Überprüfung beim Start des Computers"` + `"markiert..." 6 60 2>$OUT + + # process each disk + for disk in $1; do + local parts=$(ls /dev/${disk}* | grep "$disk\w") + parts="$(echo $parts | sed 's/\/dev\///g')" + + # process each partition + for part in $parts; do + local fstype=$(sudo lsblk -nl -o NAME,FSTYPE | grep "$part" | sed 's/\ */ /g' | cut -f 2 -d ' ') + case $fstype in + vfat) + # do nothing + ;; + ntfs) + sudo ntfsfix /dev/$part &>/dev/null + ;; + ext*) + sudo mount /dev/$part $MNT_DIR &>/dev/null + if [ $? -eq 0 ]; then + sudo touch $MNT_DIR/forcefsck &>/dev/null + fi + sudo umount $MNT_DIR &>/dev/null + ;; + esac + done + done +} + +# restore dialog: restores one or more disks with saved backups +restore() +{ + # mount store + mount_store + if [ $? -ne 0 ]; then + # show error + no_store + + return + fi + + # fill variables + local config_file=$MNT_DIR/backup_$user.conf + local disks=($(cat $config_file 2>/dev/null | cut -f 1 -d '=')) + local arch_names=($(cat $config_file 2>/dev/null | sed -e 's/.*backup_//g' -e 's/\.img//g')) + unset disks[${#disks[@]}-1] &> /dev/null + unset arch_names[${#arch_names[@]}-1] &> /dev/null + + if ! [ -e $config_file ]; then + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Wiederherstellen" --title " Fehler " --colors\ + --ok-label "Abbrechen" --hfile help.txt --exit-label "Schließen" --msgbox "\nEs ist keine Sicherung vorhanden."` + `" Bitte erstellen Sie erste eine." 8 40 + fi + + unset entries + declare -a entries + for i in $(seq 0 $((${#disks[@]}-1))); do + local entries=(${entries[@]} ${disks[$i]} "${arch_names[$i]}" off) + done + + # show dialog + while true; do + # show dialog + eval dialog --backtitle "\"RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Wiederherstellen\"" --hfile help.txt\ + --title "\" Wiederherstellung \"" --exit-label "Schließen" --colors --nocancel --ok-label "Weiter"\ + --extra-button --extra-label "Abbrechen" --checklist "\"Wählen Sie einen oder mehrere Datenträger aus, die Sie"` + `" wiederherstellen wollen.\n\Z1Achtung:\Zn Alle Daten des/der Laufwerke/s werden überschrieben!\""\ + 14 50 4 ${entries[@]} 2>$OUT + + # save choice result + local res=$? + local restore_choice="$(cat $OUT)" + + if ! [ $res -eq $DIALOG_OK ]; then + unmount_store + return + fi + + if [ -z "$restore_choice" ]; then + # show error + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Wiederherstellen" --title " Fehler " --colors\ + --ok-label "Weiter" --hfile help.txt --exit-label "Schließen" --msgbox "\nBitte wählen Sie mindestens ein"` + `" Laufwerk aus." 8 40 + + # show dialog again + continue + fi + + # end loop + break + done + + # process each disk + i=1 + count=$(echo $restore_choice | wc -w) + for disk in $restore_choice; do + # set size and name + local psize=$(($(sudo fdisk -l 2>/dev/null | grep "${disk}:" | cut -f 5 -d ' ')/1024)) + local arch_name="${arch_names[$((i-1))]}" + + # start extraction process + echo -n "" > $PROGRESS_FILE &>/dev/null + (sudo 7zr e -bd -so $MNT_DIR/backup_$arch_name.img 2>/dev/null | pv -s ${psize}k -n 2>$PROGRESS_FILE |\ + sudo dd of=/dev/$disk conv=notrunc 2>/dev/null | : | tail -fn0 $PROGRESS_FILE 2>/dev/null |\ + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Wiederherstellen" --colors\ + --title " Wiederherstellung $i/$count " --hfile help.txt --exit-label "Schließen" --gauge "Wiederherstellung"` + `" von \Z4${disk}\Zn durch \Z4${store_path}\\backup_$arch_name.img\Zn" 8 60)& + + # supervise extraction process + sleep 2 + while true; do + sleep 1 + local run=$(ps -e | grep 7zr) + + if [ -z "$run" ]; then + killall tail &>/dev/null + rm -f /tmp/progress &>/dev/null + break + fi + done + let 'i=i+1' + done + unset i + unset count + + # unmount store + unmount_store + + # marks partition for checking + mark4check "$restore_choice" + + # shutdown? + if [ "$auto_down" = "ja" ]; then + shutdown_computer + fi +} + +# shutdown dialog: shutdowns the computer +shutdown_computer() +{ + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Beenden" --title " Beenden " --nocancel --nook\ + --hfile help.txt --exit-label "Schließen" --pause "\nSekunden bis der Rechner heruntergefahren wird:" 9 40 5 + + # unmount store, shutdown and keeps script waiting for a while + unmount_store + sudo shutdown now &>/dev/null + sleep 60 +} + +# examines settings using different dialogs +# param 1 is the init mode, setting a value turns it on off otherwise +settings() +{ + # USB or network backup/restore + br_mode + + # enter username + username + + # collect settings according to backup/restore mode + if [ "$mode" == "USB" ]; then + store_path="$USB_PART" + else + # enter password + password + + # enter domain + dom + + # select network interface + interface + + # enter backup store + store + if [ $? -ne 0 ]; then + # show error + no_store + return + fi + fi + + # choose disk or partition + choose wizz + + # clean up method + cleanup_method + + # shutdown option + shutdown_option + + # save settings + save_settings +} + +# reads setting from a file +read_settings() +{ + if ! [ -e $SETTINGS_FILE ]; then + welcome + settings init + else + local IFS_saved=$IFS; + IFS=$'\n' + local content=($(cat $SETTINGS_FILE)) + IFS=$IFS_saved + mode="$(echo ${content[0]} | sed 's/mode=//')" + user="$(echo ${content[1]} | sed 's/user=//')" + pass="$(echo ${content[2]} | sed 's/pass=//')" + domain="$(echo ${content[3]} | sed 's/domain=//')" + interface="$(echo ${content[4]} | sed 's/interface=//')" + store_path="$(echo ${content[5]} | sed 's/store_path=//')" + backup_choice="$(echo ${content[6]} | sed 's/backup_choice=//')" + cleanup="$(echo ${content[7]} | sed 's/cleanup=//')" + auto_down="$(echo ${content[8]} | sed 's/auto_down=//')" + fi +} + +# saves the settings +save_settings() +{ + echo -n "" > $SETTINGS_FILE + + echo "mode=$mode" >> $SETTINGS_FILE + echo "user=$user" >> $SETTINGS_FILE + echo "pass=$pass" >> $SETTINGS_FILE + echo "domain=$domain" >> $SETTINGS_FILE + echo "interface=$interface" >> $SETTINGS_FILE + echo "store_path=$store_path" >> $SETTINGS_FILE + echo "backup_choice=$backup_choice" >> $SETTINGS_FILE + echo "cleanup=$cleanup" >> $SETTINGS_FILE + echo "auto_down=$auto_down" >> $SETTINGS_FILE +} + +# settings info dialog +settings_info() +{ + local password=$(if [ -z "$pass" ]; then echo ""; else echo ""; fi) + + if ! [ "$mode" == "USB" ]; then + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Übersicht" --title " Übersicht " --nocancel\ + --ok-label "Zurück" --hfile help.txt --exit-label "Schließen" --form "Übersicht der Einstellungen:" 16 65 9\ + "Modus:" 1 2 "$mode" 1 26 -30 30\ + "Benutzername:" 2 2 "$user" 2 26 -30 30\ + "Passwort:" 3 2 "$password" 3 26 -30 30\ + "Domäne:" 4 2 "$domain" 4 26 -30 30\ + "Netzwerkgerät:" 5 2 "$interface" 5 26 -30 30\ + "Netzlaufwerk:" 6 2 "$store_path" 6 26 -30 30\ + "Zu sichernde Laufwerke:" 7 2 "$backup_choice" 7 26 -30 30\ + "Laufwerke bereinigen:" 8 2 "$cleanup" 8 26 -30 30\ + "Autom. Herunterfahren:" 9 2 "$auto_down" 9 26 -30 30 2>$OUT + else + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü / Übersicht" --title " Übersicht " --nocancel\ + --ok-label "Zurück" --hfile help.txt --exit-label "Schließen" --form "Übersicht der Einstellungen:" 13 65 6\ + "Modus:" 1 2 "$mode" 1 26 -30 30\ + "Benutzername:" 2 2 "$user" 2 26 -30 30\ + "USB-Laufwerk:" 3 2 "$store_path" 3 26 -30 30\ + "Zu sichernde Laufwerke:" 4 2 "$backup_choice" 4 26 -30 30\ + "Laufwerke bereinigen:" 5 2 "$cleanup" 5 26 -30 30\ + "Autom. Herunterfahren:" 6 2 "$auto_down" 6 26 -30 30 2>$OUT + fi +} + +# main menu dialog +main_menu() +{ + while true; do + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe - Hauptmenü " --title " Hauptmenü " --colors --nocancel\ + --hfile help.txt --exit-label "Schließen" --menu "Bitte Funktion auswählen:" 12 70 5\ + Sichern "Erstellt eine Sicherung"\ + Wiederherstellen "Stellt den Zustand aus einer Sicherung her"\ + Einstellungen "Nimmt notwendige Einstellungen auf"\ + Übersicht "Zeigt die Einstellung an"\ + Beenden "Beendet RescueSys" 2>$OUT + + local menuitem=$(cat $OUT) + case $menuitem in + Sichern) + backup + ;; + Wiederherstellen) + restore + ;; + Einstellungen) + settings + ;; + Übersicht) + settings_info + ;; + Beenden) + shutdown_computer + ;; + esac + done +} + +# close dialog: close application after password request +close() +{ + local flag=0 + while true; do + # prepare mode handling + local error="\n" + if [ $flag -eq 1 ]; then + error="\Z1Eingabe ungültig\Zn\n" + fi + + # show dialog + dialog --backtitle "RescueSys v1.0 - F1 für Hilfe" --title " Applikation schließen " --hfile help.txt --colors\ + --cancel-label "Abbrechen" --insecure --ok-label "Schließen" --passwordbox "${error}Geben Sie das Passwort ein:"\ + 9 33 2>$OUT + + local resp=$? + local access=$(cat $OUT) + if [ $resp -eq 0 ]; then + #check password + if [ "rescuesys" == $access ]; then + sudo umount $MNT_DIR &>/dev/null + sudo umount $INSP_DIR &>/dev/null + clear + exit + else + flag=1 + continue + fi + else + break + fi + done +} + +# trap for interrupt signals such as Ctrl + C +trap "close" SIGHUP SIGINT SIGTERM +# disable "screensaver" +sudo setterm -blank 0 +# avoid kernel messages to appear to console +sudo bash -c "echo 0 > /proc/sys/kernel/printk" + +# read settings +read_settings + +# show main menu +main_menu diff --git a/setup b/setup new file mode 100755 index 0000000..58f4475 --- /dev/null +++ b/setup @@ -0,0 +1,83 @@ +#!/bin/sh +# +# This script is running at the end of the preseed process. It sets up +# important things for a later running such as fsck or grub and prepares +# everything for a setup finish in a guest run. Logs goes to syslog in +# guest. +# + +set -e + +echo "edit sudoers..." +sed 's/\ ALL$/\ NOPASSWD:ALL/' -i /target/etc/sudoers + +echo "set mount count..." +tune2fs -c 1 -i 1 /dev/sda1 + +echo "log dir etc. in tmpfs..." +sed 's/errors=/noatime,nodiratime,errors=/' -i /target/etc/fstab +echo "" >> /target/etc/fstab +echo "tmpfs /tmp tmpfs nosuid 0 0" >> /target/etc/fstab +echo "tmpfs /var/run tmpfs nosuid,mode=755 0 0" >> /target/etc/fstab +echo "tmpfs /var/lock tmpfs nosuid,noexec,nodev 0 0" >> /target/etc/fstab +echo "tmpfs /var/log tmpfs nosuid,noexec,nodev 0 0" >> /target/etc/fstab + +echo "clean issue..." +echo -n "" > /target/etc/issue + +echo "copy files..." +cp ubuntu-logo.png /target/usr/share/plymouth/ +cp ubuntu-logo16.png /target/usr/share/plymouth/ +cp grub.png /target/boot/grub/ +cp wpa_supplicant.conf /target/etc/wpa_supplicant/ +chmod 600 /target/etc/wpa_supplicant/wpa_supplicant.conf +cp 50-backup.rules /target/etc/udev/rules.d/ +cp initial /target/home/rescuesys/ +cp help.txt /target/home/rescuesys/ +cp rescuesys.sh /target/home/rescuesys/ +cp .dialogrc /target/home/rescuesys/ +chmod +x /target/home/rescuesys/rescuesys.sh /target/home/rescuesys/initial + +echo "change grub settings..." +sed -e 's/quiet/quiet video=1280x720/'\ + -e '/GRUB_DEFAULT=0/aGRUB_HIDDEN_TIMEOUT_QUIET=true'\ + -e '/GRUB_DEFAULT=0/aGRUB_HIDDEN_TIMEOUT=1'\ + -e 's/GRUB_TIMEOUT_STYLE/#GRUB_TIMEOUT_STYLE/'\ + -e 's/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=RescueSys/'\ + -e 's/#GRUB_GFXMODE=.*/GRUB_GFXMODE=1280x720/'\ + -e '/GRUB_GFXMODE=1280x720/aGRUB_GFSPAYLOAD=keep'\ + -e 's/#GRUB_INIT_TUNE/GRUB_INIT_TUNE/'\ + -i /target/etc/default/grub +echo "FRAMEBUFFER=y" > /target/etc/initramfs-tools/conf.d/splash + +echo "set shutdown time..." +sed 's/#DefaultTimeoutStopSec=.*/DefaultTimeoutStopSec=1s/' -i\ + /target/etc/systemd/system.conf + +echo "set autologin..." +mkdir -p /target/etc/systemd/system/getty@tty1.service.d +echo -e '[Service]\nExecStart=\nExecStart=-/sbin/agetty --autologin'` + `' rescuesys --skip-login --noissue %I $TERM\nType=idle\n' >\ + /target/etc/systemd/system/getty@tty1.service.d/override.conf + +echo "set autostart..." +echo "./initial" > /target/home/rescuesys/.bash_profile + +echo "mount target and finish setup..." +mount -o bind /dev /target/dev +mount -t sysfs sysfs /target/sys +cat << EOF | chroot /target +set -e +apt-get -y purge os-prober plymouth-theme-ubuntu-logo\ + plymouth-theme-ubuntu-text +update-grub2 +cd /usr/share/plymouth +apt-get -y download plymouth-theme-ubuntu-logo +mkdir /home/rescuesys/mnt +chown rescuesys:rescuesys /home/rescuesys/initial\ + /home/rescuesys/.bash_profile\ + /home/rescuesys/rescuesys.sh\ + /home/rescuesys/mnt +EOF +umount /target/sys +umount /target/dev diff --git a/ubuntu-logo.png b/ubuntu-logo.png new file mode 100644 index 0000000..c821c3c Binary files /dev/null and b/ubuntu-logo.png differ diff --git a/ubuntu-logo16.png b/ubuntu-logo16.png new file mode 100644 index 0000000..b1d2e45 Binary files /dev/null and b/ubuntu-logo16.png differ diff --git a/wpa_supplicant.conf b/wpa_supplicant.conf new file mode 100644 index 0000000..e8e0c50 --- /dev/null +++ b/wpa_supplicant.conf @@ -0,0 +1,14 @@ +ctrl_interface=/var/run/wpa_supplicant +eapol_version=1 +ap_scan=1 + +network={ + ssid="SSID" + psk="PASSWORD" + scan_ssid=1 + proto=RSN WPA + key_mgmt=WPA-PSK + pairwise=CCMP TKIP + group=CCMP TKIP +} +