Finish writing the apply changes functions

This commit is contained in:
HikariKnight 2023-04-12 01:19:02 +02:00
parent e7c61c564e
commit 4c99baeed8
6 changed files with 133 additions and 24 deletions

View file

@ -86,7 +86,7 @@ func Set_KernelStub() string {
errorcheck.ErrorCheck(err, "Error, kernelstub command returned exit code 1") errorcheck.ErrorCheck(err, "Error, kernelstub command returned exit code 1")
// Return what we did // Return what we did
return fmt.Sprintf("sudo kernelstub -a \"%s\"", kernel_args) return fmt.Sprintf("Executed: sudo kernelstub -a \"%s\"", kernel_args)
} }
// Configures grub2 and/or systemd-boot using grubby // Configures grub2 and/or systemd-boot using grubby
@ -105,7 +105,7 @@ func Set_Grubby() string {
errorcheck.ErrorCheck(err, "Error, grubby command returned exit code 1") errorcheck.ErrorCheck(err, "Error, grubby command returned exit code 1")
// Return what we did // Return what we did
return fmt.Sprintf("sudo grubby --update-kernel=ALL --args=\"%s\"", kernel_args) return fmt.Sprintf("Executed: sudo grubby --update-kernel=ALL --args=\"%s\"", kernel_args)
} }
func Configure_Grub2() { func Configure_Grub2() {
@ -206,21 +206,23 @@ func Set_Grub2() ([]string, error) {
// Get the conf file // Get the conf file
conffile := fmt.Sprintf("%s/grub", config.Path.DEFAULT) conffile := fmt.Sprintf("%s/grub", config.Path.DEFAULT)
// Get the sysfile
sysfile_re := regexp.MustCompile(`^config`)
sysfile := sysfile_re.ReplaceAllString(conffile, "")
// Write to logger // Write to logger
logger.Printf("Executing command:\nsudo cp -v \"%s\" /etc/default/grub", conffile) logger.Printf("Executing command:\nsudo cp -v \"%s\" %s", conffile, sysfile)
// Since we should be elevated with our sudo token we will copy with cp // Make our output slice
// (using built in functions will not work as we are running as the normal user) var output []string
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 // Copy files to system
logger.Printf(strings.Join(output, "\n")) output = append(output, CopyToSystem(conffile, sysfile))
// Set a variable for the mkconfig command // Set a variable for the mkconfig command
mkconfig := "grub-mkconfig" mkconfig := "grub-mkconfig"
// Check for grub-mkconfig // Check for grub-mkconfig
_, err = command.Run("which", "grub-mkconfig") _, err := command.Run("which", "grub-mkconfig")
if err == nil { if err == nil {
// Set binary as grub-mkconfig // Set binary as grub-mkconfig
mkconfig = "grub-mkconfig" mkconfig = "grub-mkconfig"
@ -230,12 +232,12 @@ func Set_Grub2() ([]string, error) {
// Update grub.cfg // Update grub.cfg
if fileio.FileExist("/boot/grub/grub.cfg") { if fileio.FileExist("/boot/grub/grub.cfg") {
output = append(output, fmt.Sprintf("sudo %s -o /boot/grub/grub.cfg", mkconfig)) output = append(output, fmt.Sprintf("Executed: sudo %s -o /boot/grub/grub.cfg\nSee debug.log for more detailed output", mkconfig))
mklog, err := command.Run("sudo", mkconfig, "-o", "/boot/grub/grub.cfg") mklog, err := command.Run("sudo", mkconfig, "-o", "/boot/grub/grub.cfg")
logger.Printf(strings.Join(mklog, "\n")) logger.Printf(strings.Join(mklog, "\n"))
errorcheck.ErrorCheck(err, "Failed to update /boot/grub/grub.cfg") errorcheck.ErrorCheck(err, "Failed to update /boot/grub/grub.cfg")
} else { } else {
output = append(output, fmt.Sprintf("sudo %s -o /boot/grub/grub.cfg\nSee debug.log for more detailed output", mkconfig)) output = append(output, fmt.Sprintf("Executed: 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") mklog, err := command.Run("sudo", mkconfig, "-o", "/boot/grub2/grub.cfg")
logger.Printf(strings.Join(mklog, "\n")) logger.Printf(strings.Join(mklog, "\n"))
errorcheck.ErrorCheck(err, "Failed to update /boot/grub/grub.cfg") errorcheck.ErrorCheck(err, "Failed to update /boot/grub/grub.cfg")

View file

@ -7,6 +7,7 @@ import (
"github.com/HikariKnight/ls-iommu/pkg/errorcheck" "github.com/HikariKnight/ls-iommu/pkg/errorcheck"
"github.com/HikariKnight/quickpassthrough/internal/logger" "github.com/HikariKnight/quickpassthrough/internal/logger"
"github.com/HikariKnight/quickpassthrough/pkg/command"
"github.com/HikariKnight/quickpassthrough/pkg/fileio" "github.com/HikariKnight/quickpassthrough/pkg/fileio"
"github.com/HikariKnight/quickpassthrough/pkg/uname" "github.com/HikariKnight/quickpassthrough/pkg/uname"
"github.com/klauspost/cpuid/v2" "github.com/klauspost/cpuid/v2"
@ -218,3 +219,20 @@ func makeBackupDir(dest string) {
err := os.MkdirAll(fmt.Sprintf("backup/%s", dest), os.ModePerm) err := os.MkdirAll(fmt.Sprintf("backup/%s", dest), os.ModePerm)
errorcheck.ErrorCheck(err, "Error making backup/ folder") errorcheck.ErrorCheck(err, "Error making backup/ folder")
} }
// Copy a file to the system, make sure you have run command.Elevate() recently
func CopyToSystem(conffile, sysfile string) string {
// 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, _ := command.Run("sudo", "cp", "-v", conffile, sysfile)
// Clean the output
clean_re := regexp.MustCompile(`\n`)
clean_output := clean_re.ReplaceAllString(output[0], "")
// Write output to logger
logger.Printf(clean_output)
// Return the output
return fmt.Sprintf("Copying: %s", clean_output)
}

View file

@ -2,6 +2,7 @@ package internal
import ( import (
"encoding/base64" "encoding/base64"
"fmt"
"github.com/HikariKnight/quickpassthrough/internal/logger" "github.com/HikariKnight/quickpassthrough/internal/logger"
"github.com/HikariKnight/quickpassthrough/pkg/command" "github.com/HikariKnight/quickpassthrough/pkg/command"
@ -52,7 +53,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "enter": case "enter":
// If we are on the INSTALL dialog // If we are on the INSTALL dialog
if m.focused == INSTALL { if m.focused == INSTALL && m.authDialog.Value() != "" {
// Write to logger // Write to logger
logger.Printf("Getting authentication token by elevating with sudo once") logger.Printf("Getting authentication token by elevating with sudo once")
@ -71,14 +72,16 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Blank the password field // Blank the password field
m.authDialog.SetValue("") m.authDialog.SetValue("")
fmt.Println("Working... Application frozen until done, check debug.log for progress")
// Start installation and send the password to the command // Start installation and send the password to the command
m.installOutput = m.install() m.install()
// Move to the DONE dialog // Move to the DONE dialog
m.focused++ m.focused = DONE
// Exit the alt screen as the output on the done dialog needs to be scrollable // Exit the alt screen as the output on the done dialog needs to be scrollable
//return m, tea.ExitAltScreen return m, tea.ClearScreen
} else { } else {
// Quit the application if we are on a different view // Quit the application if we are on a different view

View file

@ -4,11 +4,14 @@ import (
"fmt" "fmt"
"os" "os"
"regexp" "regexp"
"strings"
"github.com/HikariKnight/ls-iommu/pkg/errorcheck" "github.com/HikariKnight/ls-iommu/pkg/errorcheck"
"github.com/HikariKnight/quickpassthrough/internal/configs" "github.com/HikariKnight/quickpassthrough/internal/configs"
"github.com/HikariKnight/quickpassthrough/internal/logger" "github.com/HikariKnight/quickpassthrough/internal/logger"
"github.com/HikariKnight/quickpassthrough/pkg/command"
"github.com/HikariKnight/quickpassthrough/pkg/fileio" "github.com/HikariKnight/quickpassthrough/pkg/fileio"
"github.com/HikariKnight/quickpassthrough/pkg/uname"
) )
// This function processes the enter event // This function processes the enter event
@ -151,7 +154,7 @@ func (m *model) processSelection() bool {
// This function starts the install process // This function starts the install process
// It takes 1 auth string as variable // It takes 1 auth string as variable
func (m *model) install() []string { func (m *model) install() {
// Get the config // Get the config
config := configs.GetConfig() config := configs.GetConfig()
@ -159,7 +162,7 @@ func (m *model) install() []string {
var output []string var output []string
// Based on the bootloader, setup the configuration // Based on the bootloader, setup the configuration
if config.Bootloader != "kernelstub" { if config.Bootloader == "kernelstub" {
// Write to logger // Write to logger
logger.Printf("Configuring systemd-boot using kernelstub") logger.Printf("Configuring systemd-boot using kernelstub")
@ -173,7 +176,7 @@ func (m *model) install() []string {
// Configure kernelstub // Configure kernelstub
output = append(output, configs.Set_Grubby()) output = append(output, configs.Set_Grubby())
} else if config.Bootloader != "grub2" { } else if config.Bootloader == "grub2" {
// Write to logger // Write to logger
logger.Printf("Configuring grub2 manually") logger.Printf("Configuring grub2 manually")
grub_output, _ := configs.Set_Grub2() grub_output, _ := configs.Set_Grub2()
@ -184,5 +187,71 @@ func (m *model) install() []string {
logger.Printf("Unsupported bootloader, please add the below line to your bootloaders kernel arguments\n%s", kernel_args) logger.Printf("Unsupported bootloader, please add the below line to your bootloaders kernel arguments\n%s", kernel_args)
} }
return output // A lot of linux systems support modprobe along with their own module system
// So copy the modprobe files if we have them
modprobeFile := fmt.Sprintf("%s/vfio.conf", config.Path.MODPROBE)
if fileio.FileExist(modprobeFile) {
// Copy initramfs-tools module to system
output = append(output, configs.CopyToSystem(modprobeFile, "/etc/modprobe.d/vfio.conf"))
}
// Copy the config files for the system we have
initramfsFile := fmt.Sprintf("%s/modules", config.Path.INITRAMFS)
dracutFile := fmt.Sprintf("%s/vfio.conf", config.Path.DRACUT)
if fileio.FileExist(initramfsFile) {
// Copy initramfs-tools module to system
output = append(output, configs.CopyToSystem(initramfsFile, "/etc/initramfs-tools/modules"))
// Copy the modules file to /etc/modules
output = append(output, configs.CopyToSystem(config.Path.ETCMODULES, "/etc/modules"))
// Write to logger
logger.Printf("Executing: sudo update-initramfs -u")
// Update initramfs
output = append(output, "Executed: sudo update-initramfs -u\nSee debug.log for detailed output")
cmd_out, cmd_err, _ := command.RunErr("sudo", "update-initramfs", "-u")
cmd_out = append(cmd_out, cmd_err...)
// Write to logger
logger.Printf(strings.Join(cmd_out, "\n"))
} else if fileio.FileExist(dracutFile) {
// Copy dracut config to /etc/dracut.conf.d/vfio
output = append(output, configs.CopyToSystem(dracutFile, "/etc/dracut.conf.d/vfio"))
// Get systeminfo
sysinfo := uname.New()
// Write to logger
logger.Printf("Executing: sudo dracut -f -v --kver %s", sysinfo.Release)
// Update initramfs
output = append(output, fmt.Sprintf("Executed: sudo dracut -f -v --kver %s\nSee debug.log for detailed output", sysinfo.Release))
cmd_out, cmd_err, _ := command.RunErr("sudo", "dracut", "-f", "-v", "--kver", sysinfo.Release)
cmd_out = append(cmd_out, cmd_err...)
// Write to logger
logger.Printf(strings.Join(cmd_out, "\n"))
} else if fileio.FileExist(config.Path.MKINITCPIO) {
// Copy dracut config to /etc/dracut.conf.d/vfio
output = append(output, configs.CopyToSystem(config.Path.MKINITCPIO, "/etc/mkinitcpio.conf"))
// Write to logger
logger.Printf("Executing: sudo mkinitcpio -P")
// Update initramfs
output = append(output, "Executed: sudo mkinitcpio -P\nSee debug.log for detailed output")
cmd_out, cmd_err, _ := command.RunErr("sudo", "mkinitcpio", "-P")
cmd_out = append(cmd_out, cmd_err...)
// Write to logger
logger.Printf(strings.Join(cmd_out, "\n"))
}
m.installOutput = output
m.focused++
} }

View file

@ -6,6 +6,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
) )
@ -20,7 +21,7 @@ func (m model) View() string {
titleStyle.MarginLeft(0).Render("Welcome to QuickPassthrough!"), titleStyle.MarginLeft(0).Render("Welcome to QuickPassthrough!"),
"\n\n", "\n\n",
"This script is meant to make it easier to setup GPU passthrough for\n", "This script is meant to make it easier to setup GPU passthrough for\n",
"Qemu based systems.\n", "Qemu based systems. WITH 2 GPUS ON THE HOST SYSTEM\n",
"However due to the complexity of GPU passthrough\n", "However due to the complexity of GPU passthrough\n",
"This script assumes you know how to do (or have done) the following.\n\n", "This script assumes you know how to do (or have done) the following.\n\n",
"* You have already enabled IOMMU, VT-d, SVM and/or AMD-v\n inside your UEFI/BIOS advanced settings.\n", "* You have already enabled IOMMU, VT-d, SVM and/or AMD-v\n inside your UEFI/BIOS advanced settings.\n",
@ -138,9 +139,16 @@ func (m model) View() string {
view = m.authDialog.View() view = m.authDialog.View()
case WORKING:
title = titleStyle.Render("Applying configurations!")
view = ""
m.authDialog.Update(tea.KeyEnter)
tea.Batch()
case DONE: case DONE:
title = titleStyle.Render("Applying configurations!") title = titleStyle.Render("Applying configurations!")
view = dialogStyle.Render(strings.Join(m.installOutput, "\n")) view = dialogStyle.Render(fmt.Sprintf("%s\n\nPress Enter to Exit.", strings.Join(m.installOutput, "\n")))
} }
//return listStyle.SetString(fmt.Sprintf("%s\n\n", title)).Render(m.lists[m.focused].View()) //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)) return lipgloss.JoinVertical(lipgloss.Left, fmt.Sprintf("%s\n%s\n", title, view))

View file

@ -49,6 +49,7 @@ const (
USB USB
USB_GROUP USB_GROUP
INSTALL INSTALL
WORKING
DONE DONE
) )
@ -99,14 +100,15 @@ func (m *model) initLists(width, height int) {
defaultList, defaultList,
choiceList, choiceList,
choiceList, choiceList,
choiceList,
} }
// Configure offsets for sizing // Configure offsets for sizing
m.offsetx = []int{ m.offsetx = []int{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
} }
m.offsety = []int{ m.offsety = []int{
18, 2, 3, 13, 5, 2, 3, 12, 0, 18, 2, 3, 13, 5, 2, 3, 12, 0, 0,
} }
// Update the styles with the correct width // Update the styles with the correct width
@ -167,6 +169,13 @@ func (m *model) initLists(width, height int) {
m.lists[VIDEO].SetItems(items) m.lists[VIDEO].SetItems(items)
m.lists[VIDEO].SetSize(m.width-m.offsetx[VIDEO], m.height-m.offsety[VIDEO]) m.lists[VIDEO].SetSize(m.width-m.offsetx[VIDEO], m.height-m.offsety[VIDEO])
// Init DONE choises
items = []list.Item{
item{title: "WAITING"},
}
m.lists[WORKING].SetItems(items)
m.lists[WORKING].SetSize(m.width-m.offsetx[WORKING], m.height-m.offsety[WORKING])
// Init DONE choises // Init DONE choises
items = []list.Item{ items = []list.Item{
item{title: "FINISH"}, item{title: "FINISH"},