/*
* RestoreDeviceBox.vala
*
* Copyright 2012-2018 Tony George <teejeetech@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
using Gtk;
using Gee;
using TeeJee.Logging;
using TeeJee.FileSystem;
using TeeJee.JsonHelper;
using TeeJee.ProcessHelper;
using TeeJee.GtkHelper;
using TeeJee.System;
using TeeJee.Misc;
class BootOptionsBox : Gtk.Box{
private Gtk.Box option_box;
private Gtk.ComboBox cmb_grub_dev;
private Gtk.CheckButton chk_reinstall_grub;
private Gtk.CheckButton chk_update_initramfs;
private Gtk.CheckButton chk_update_grub;
private Gtk.Window parent_window;
public BootOptionsBox (Gtk.Window _parent_window) {
log_debug("BootOptionsBox: BootOptionsBox()");
//base(Gtk.Orientation.VERTICAL, 6); // issue with vala
GLib.Object(orientation: Gtk.Orientation.VERTICAL, spacing: 6); // work-around
parent_window = _parent_window;
margin = 12;
// options
option_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
add(option_box);
add_bootloader_options();
refresh_options();
log_debug("BootOptionsBox: BootOptionsBox(): exit");
}
private void add_bootloader_options(){
// header
//var label = add_label_header(this, _("Select Bootloader Options"), true);
add_chk_reinstall_grub();
var hbox = new Gtk.Box(Orientation.HORIZONTAL, 6);
hbox.margin_start = 12;
add (hbox);
//cmb_grub_dev
cmb_grub_dev = new ComboBox ();
cmb_grub_dev.hexpand = true;
hbox.add(cmb_grub_dev);
var cell_text = new CellRendererText ();
cell_text.text = "";
cmb_grub_dev.pack_start(cell_text, false);
cell_text = new CellRendererText();
cmb_grub_dev.pack_start(cell_text, false);
cmb_grub_dev.set_cell_data_func(cell_text, (cell_layout, cell, model, iter)=>{
Device dev;
model.get (iter, 0, out dev, -1);
if (dev.type == "disk"){
//log_msg("desc:" + dev.description());
((Gtk.CellRendererText)cell).markup =
"<b>%s (MBR)</b>".printf(dev.description_formatted());
}
else{
((Gtk.CellRendererText)cell).text = dev.description();
}
});
cmb_grub_dev.changed.connect(()=>{
save_grub_device_selection();
});
/*string tt = "<b>" + _("** Advanced Users **") + "</b>\n\n"+ _("Skips bootloader (re)installation on target device.\nFiles in /boot directory on target partition will remain untouched.\n\nIf you are restoring a system that was bootable previously then it should boot successfully. Otherwise the system may fail to boot.");*/
hbox = new Gtk.Box(Orientation.HORIZONTAL, 6);
add (hbox);
add_chk_update_initramfs(hbox);
add_chk_update_grub(hbox);
}
private void add_chk_reinstall_grub(){
var chk = new CheckButton.with_label(_("(Re)install GRUB2 on:"));
chk.active = false;
chk.set_tooltip_markup(_("Re-installs the GRUB2 bootloader on the selected device."));
//chk.margin_bottom = 12;
add (chk);
chk_reinstall_grub = chk;
chk.toggled.connect(()=>{
cmb_grub_dev.sensitive = chk_reinstall_grub.active;
App.reinstall_grub2 = chk_reinstall_grub.active;
cmb_grub_dev.changed();
});
}
private void add_chk_update_initramfs(Gtk.Box hbox){
//chk_update_initramfs
var chk = new CheckButton.with_label(_("Update initramfs"));
chk.active = false;
chk.set_tooltip_markup(_("Re-generates initramfs for all installed kernels. This is generally not needed. Select this only if the restored system fails to boot."));
//chk.margin_bottom = 12;
add (chk);
chk_update_initramfs = chk;
chk.toggled.connect(()=>{
App.update_initramfs = chk_update_initramfs.active;
});
}
private void add_chk_update_grub(Gtk.Box hbox){
//chk_update_grub
var chk = new CheckButton.with_label(_("Update GRUB menu"));
chk.active = false;
chk.set_tooltip_markup(_("Updates the GRUB menu entries (recommended). This is safe to run and should be left selected."));
//chk.margin_bottom = 12;
add (chk);
chk_update_grub = chk;
chk.toggled.connect(()=>{
App.update_grub = chk_update_grub.active;
});
}
private void save_grub_device_selection(){
App.grub_device = "";
if (App.reinstall_grub2){
Device entry;
TreeIter iter;
bool ok = cmb_grub_dev.get_active_iter (out iter);
if (!ok) { return; } // not selected
TreeModel model = (TreeModel) cmb_grub_dev.model;
model.get(iter, 0, out entry);
App.grub_device = entry.device;
}
}
private void refresh_options(){
refresh_cmb_grub_dev();
chk_reinstall_grub.active = App.reinstall_grub2;
cmb_grub_dev.sensitive = chk_reinstall_grub.active;
chk_update_initramfs.active = App.update_initramfs;
chk_update_grub.active = App.update_grub;
chk_reinstall_grub.sensitive = true;
chk_update_initramfs.sensitive = true;
chk_update_grub.sensitive = true;
if (App.mirror_system){
// bootloader must be re-installed
chk_reinstall_grub.sensitive = false;
chk_update_initramfs.sensitive = false;
chk_update_grub.sensitive = false;
}
else{
if (App.snapshot_to_restore.distro.dist_id == "fedora"){
// grub2-install should never be run on EFI fedora systems
chk_reinstall_grub.sensitive = false;
}
}
}
private void refresh_cmb_grub_dev(){
var store = new Gtk.ListStore(2, typeof(Device), typeof(string));
TreeIter iter;
foreach(Device dev in Device.get_block_devices_using_lsblk()) {
// select disk and normal partitions, skip others (loop crypt rom lvm)
if ((dev.type != "disk") && (dev.type != "part")){
continue;
}
// skip luks and lvm2 partitions
if ((dev.fstype == "luks")||(dev.fstype == "lvm2")){
continue;
}
// skip extended partitions
if (dev.size_bytes < 10 * KB){
continue;
}
store.append(out iter);
store.set (iter, 0, dev);
store.set (iter, 1, IconManager.ICON_HARDDRIVE);
}
cmb_grub_dev.model = store;
cmb_grub_dev_select_default();
}
private void cmb_grub_dev_select_default(){
if ((cmb_grub_dev == null) || (cmb_grub_dev.model == null)){
return;
}
log_debug("BootOptionsBox: cmb_grub_dev_select_default()");
if (App.grub_device.length == 0){
cmb_grub_dev.active = -1;
return;
}
TreeIter iter;
var store = (Gtk.ListStore) cmb_grub_dev.model;
int index = -1;
int active = -1;
for (bool next = store.get_iter_first (out iter); next; next = store.iter_next (ref iter)) {
Device dev_iter;
store.get(iter, 0, out dev_iter);
index++;
if (dev_iter.device == App.grub_device){
active = index;
break;
}
}
cmb_grub_dev.active = active;
log_debug("BootOptionsBox: cmb_grub_dev_select_default(): exit");
}
}