diff --git a/internal/configs/config_bootloaders.go b/internal/configs/config_bootloaders.go index 5d33e99..0ba4128 100644 --- a/internal/configs/config_bootloaders.go +++ b/internal/configs/config_bootloaders.go @@ -17,13 +17,20 @@ import ( // Preference is given to kernelstub because it is WAY easier to safely edit compared to grub2 func getBootloader(config *Config) { // Check what bootloader handler we are using - // Check for grub-mkconfig + // Check for grub2-mkconfig _, err := command.Run("which", "grub2-mkconfig") if err == nil { // Mark bootloader as grub2 config.Bootloader = "grub2" } + // Check for grub2-mkconfig + _, err = command.Run("which", "grub-mkconfig") + if err == nil { + // Mark bootloader as grub2 + config.Bootloader = "grub2" + } + // Check for grubby (used by fedora) _, err = command.Run("which", "grubby") if err == nil { @@ -64,7 +71,7 @@ func Set_Cmdline(gpu_IDs []string) { } // Configures systemd-boot using kernelstub -func Set_KernelStub() { +func Set_KernelStub() string { // Get the config config := GetConfig() @@ -77,10 +84,13 @@ func Set_KernelStub() { // Run the command _, err := command.Run("sudo", "kernelstub", "-a", kernel_args) errorcheck.ErrorCheck(err, "Error, kernelstub command returned exit code 1") + + // Return what we did + return fmt.Sprintf("sudo kernelstub -a \"%s\"", kernel_args) } // Configures grub2 and/or systemd-boot using grubby -func Set_Grubby() { +func Set_Grubby() string { // Get the config config := GetConfig() @@ -93,9 +103,12 @@ func Set_Grubby() { // Run the command _, err := command.Run("sudo", "grubby", "--update-kernel=ALL", fmt.Sprintf("--args=%s", kernel_args)) errorcheck.ErrorCheck(err, "Error, grubby command returned exit code 1") + + // Return what we did + return fmt.Sprintf("sudo grubby --update-kernel=ALL --args=\"%s\"", kernel_args) } -func Set_Grub2() { +func Configure_Grub2() { // Get the config struct config := GetConfig() @@ -184,3 +197,49 @@ func clean_Grub2_Args(old_kernel_args []string) []string { // Return cleaned up arguments return clean_kernel_args } + +// This function copies our config to /etc/default/grub and updates grub +func Set_Grub2() ([]string, error) { + // Get the config + config := GetConfig() + + // Get the conf file + conffile := fmt.Sprintf("%s/grub", config.Path.DEFAULT) + + // Write to logger + logger.Printf("Executing command:\nsudo cp -v \"%s\" /etc/default/grub", conffile) + + // Since we should be elevated with our sudo token we will copy with cp + // (using built in functions will not work as we are running as the normal user) + output, err := command.Run("sudo", "cp", "-v", conffile, "/etc/default/grub") + errorcheck.ErrorCheck(err, fmt.Sprintf("Failed to copy %s to /etc/default/grub", conffile)) + + // Write output to logger + logger.Printf(strings.Join(output, "\n")) + + // Set a variable for the mkconfig command + mkconfig := "grub-mkconfig" + // Check for grub-mkconfig + _, err = command.Run("which", "grub-mkconfig") + if err == nil { + // Set binary as grub-mkconfig + mkconfig = "grub-mkconfig" + } else { + mkconfig = "grub2-mkconfig" + } + + // Update grub.cfg + if fileio.FileExist("/boot/grub/grub.cfg") { + output = append(output, fmt.Sprintf("sudo %s -o /boot/grub/grub.cfg", mkconfig)) + mklog, err := command.Run("sudo", mkconfig, "-o", "/boot/grub/grub.cfg") + logger.Printf(strings.Join(mklog, "\n")) + errorcheck.ErrorCheck(err, "Failed to update /boot/grub/grub.cfg") + } else { + output = append(output, fmt.Sprintf("sudo %s -o /boot/grub/grub.cfg\nSee debug.log for more detailed output", mkconfig)) + mklog, err := command.Run("sudo", mkconfig, "-o", "/boot/grub2/grub.cfg") + logger.Printf(strings.Join(mklog, "\n")) + errorcheck.ErrorCheck(err, "Failed to update /boot/grub/grub.cfg") + } + + return output, err +} diff --git a/internal/ui_main_events.go b/internal/ui_main_events.go index 398780d..c85259f 100644 --- a/internal/ui_main_events.go +++ b/internal/ui_main_events.go @@ -23,8 +23,10 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "enter": if m.width != 0 { - // Process the selected item, if the return value is true then exit the application - m.processSelection() + // Process the selected item, if the return value is true then exit alt screen + if !m.processSelection() { + return m, tea.ExitAltScreen + } } case "ctrl+z", "backspace": // Go backwards in the model @@ -70,13 +72,13 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.authDialog.SetValue("") // Start installation and send the password to the command - m.install() + m.installOutput = m.install() // Move to the DONE dialog m.focused++ // Exit the alt screen as the output on the done dialog needs to be scrollable - return m, tea.ExitAltScreen + //return m, tea.ExitAltScreen } else { // Quit the application if we are on a different view diff --git a/internal/ui_main_functions.go b/internal/ui_main_functions.go index 4b8f058..265d722 100644 --- a/internal/ui_main_functions.go +++ b/internal/ui_main_functions.go @@ -118,6 +118,13 @@ func (m *model) processSelection() bool { configs.Set_Mkinitcpio() } + // Configure grub2 here as we can make the config without sudo + if config.Bootloader == "grub2" { + // Write to logger + logger.Printf("Configuring grub2 manually") + configs.Configure_Grub2() + } + // Go to the next view //m.focused++ @@ -144,31 +151,38 @@ func (m *model) processSelection() bool { // This function starts the install process // It takes 1 auth string as variable -func (m *model) install() { +func (m *model) install() []string { // Get the config config := configs.GetConfig() + // Make a stringlist to keep the output to show the user + var output []string + // Based on the bootloader, setup the configuration - if config.Bootloader == "kernelstub" { + if config.Bootloader != "kernelstub" { // Write to logger logger.Printf("Configuring systemd-boot using kernelstub") // Configure kernelstub - configs.Set_KernelStub() + output = append(output, configs.Set_KernelStub()) } else if config.Bootloader == "grubby" { // Write to logger logger.Printf("Configuring bootloader using grubby") // Configure kernelstub - configs.Set_Grubby() + output = append(output, configs.Set_Grubby()) - } else if config.Bootloader == "grub2" { + } else if config.Bootloader != "grub2" { // Write to logger logger.Printf("Configuring grub2 manually") - configs.Set_Grub2() + grub_output, _ := configs.Set_Grub2() + output = append(output, grub_output...) + } else { kernel_args := fileio.ReadFile(config.Path.CMDLINE) logger.Printf("Unsupported bootloader, please add the below line to your bootloaders kernel arguments\n%s", kernel_args) } + + return output } diff --git a/internal/ui_main_view.go b/internal/ui_main_view.go index dc15225..b4c52ea 100644 --- a/internal/ui_main_view.go +++ b/internal/ui_main_view.go @@ -12,7 +12,7 @@ import ( func (m model) View() string { if m.width != 0 { title := "" - view := "Empty View :(" + view := "" switch m.focused { case INTRO: title = dialogStyle.Render( @@ -137,6 +137,10 @@ func (m model) View() string { ) view = m.authDialog.View() + + case DONE: + title = titleStyle.Render("Applying configurations!") + view = dialogStyle.Render(strings.Join(m.installOutput, "\n")) } //return listStyle.SetString(fmt.Sprintf("%s\n\n", title)).Render(m.lists[m.focused].View()) return lipgloss.JoinVertical(lipgloss.Left, fmt.Sprintf("%s\n%s\n", title, view)) diff --git a/internal/ui_model.go b/internal/ui_model.go index 0846553..257019d 100644 --- a/internal/ui_model.go +++ b/internal/ui_model.go @@ -25,17 +25,18 @@ func (i item) FilterValue() string { return i.title } // Main Model type model struct { - fetched []bool - lists []list.Model - gpu_group string - gpu_IDs []string - vbios_path string - focused status - offsetx []int - offsety []int - width int - height int - authDialog textinput.Model + fetched []bool + lists []list.Model + gpu_group string + gpu_IDs []string + vbios_path string + focused status + offsetx []int + offsety []int + width int + height int + authDialog textinput.Model + installOutput []string } // Consts used to navigate the main model