fixes to test plugins by os.Exec()
This commit is contained in:
parent
de6b45ced2
commit
edb3e23311
6
Makefile
6
Makefile
|
@ -3,14 +3,16 @@ GUIVERSION = $(shell git describe --tags)
|
||||||
BUILDTIME = $(shell date +%Y.%m.%d)
|
BUILDTIME = $(shell date +%Y.%m.%d)
|
||||||
|
|
||||||
all: verbose
|
all: verbose
|
||||||
./fixup drives
|
-fixup --gui-check-plugin ../../../toolkits/gocui/gocui.so
|
||||||
|
fixup --gui gocui --gui-verbose --gui-file ../../toolkits/gocui/gocui.so drives
|
||||||
|
|
||||||
go-build: goimports
|
go-build: goimports
|
||||||
GO111MODULE=off go build \
|
GO111MODULE=off go build \
|
||||||
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
||||||
|
|
||||||
verbose: goimports
|
verbose: goimports
|
||||||
GO111MODULE=off go build -v -x \
|
-cp -a ../../../toolkits/gocui/gocui.so resources/
|
||||||
|
GO111MODULE=off go install -v -x \
|
||||||
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
||||||
|
|
||||||
install: goimports
|
install: goimports
|
||||||
|
|
2
argv.go
2
argv.go
|
@ -59,5 +59,5 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args) Version() string {
|
func (args) Version() string {
|
||||||
return "wit-test " + VERSION + " Built on " + BUILDTIME
|
return ARGNAME + " " + VERSION + " Built on " + BUILDTIME
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,6 @@ import (
|
||||||
handles shell autocomplete
|
handles shell autocomplete
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// used for shell auto completion
|
|
||||||
var ARGNAME string = "wit-test" // todo: get this from $0 ?
|
|
||||||
|
|
||||||
func (args) doBashAuto() {
|
func (args) doBashAuto() {
|
||||||
argv.doBashHelp()
|
argv.doBashHelp()
|
||||||
switch argv.BashAuto[0] {
|
switch argv.BashAuto[0] {
|
||||||
|
@ -68,6 +65,8 @@ func (args) doBash() {
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println("# todo: add this to go-arg as a 'hidden' go-arg option --bash")
|
fmt.Println("# todo: add this to go-arg as a 'hidden' go-arg option --bash")
|
||||||
fmt.Println("#")
|
fmt.Println("#")
|
||||||
|
fmt.Println("# Put the below in the file: ~/.local/share/bash-completion/completions/" + ARGNAME)
|
||||||
|
fmt.Println("#")
|
||||||
fmt.Println("# todo: make this output work/parse with:")
|
fmt.Println("# todo: make this output work/parse with:")
|
||||||
fmt.Println("# complete -C " + ARGNAME + " --bash go")
|
fmt.Println("# complete -C " + ARGNAME + " --bash go")
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
15
doDrives.go
15
doDrives.go
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -18,7 +17,7 @@ func doDrives() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range parts {
|
for _, p := range parts {
|
||||||
fmt.Printf("Device: /dev/%s\tSize: %d KiB\n", p.Name, p.Blocks)
|
log.Printf("Device: /dev/%s\tSize: %d KiB\n", p.Name, p.Blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
blockDir := "/sys/block"
|
blockDir := "/sys/block"
|
||||||
|
@ -33,7 +32,7 @@ func doDrives() {
|
||||||
if d.IsDir() && filepath.Dir(path) == blockDir {
|
if d.IsDir() && filepath.Dir(path) == blockDir {
|
||||||
dev := d.Name()
|
dev := d.Name()
|
||||||
devPath := "/dev/" + dev
|
devPath := "/dev/" + dev
|
||||||
fmt.Printf("Drive: %s\n", devPath)
|
log.Printf("Drive: %s\n", devPath)
|
||||||
|
|
||||||
// Look for partitions
|
// Look for partitions
|
||||||
partitions, err := filepath.Glob(filepath.Join(blockDir, dev, dev+"*"))
|
partitions, err := filepath.Glob(filepath.Join(blockDir, dev, dev+"*"))
|
||||||
|
@ -51,18 +50,18 @@ func doDrives() {
|
||||||
hasPartition = true
|
hasPartition = true
|
||||||
partDev := "/dev/" + partName
|
partDev := "/dev/" + partName
|
||||||
isMounted := mounts[partDev]
|
isMounted := mounts[partDev]
|
||||||
fmt.Printf(" Partition: %s [%v]\n", partDev, isMounted)
|
log.Printf(" Partition: %s [%v]\n", partDev, isMounted)
|
||||||
if isMounted {
|
if isMounted {
|
||||||
used = true
|
used = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasPartition {
|
if !hasPartition {
|
||||||
fmt.Println(" No partitions found.")
|
log.Println(" No partitions found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !used {
|
if !used {
|
||||||
fmt.Println(" → Drive appears to be unused.")
|
log.Println(" → Drive appears to be unused.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -127,9 +126,9 @@ func parseProcPartitions() ([]Partition, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var p Partition
|
var p Partition
|
||||||
_, err := fmt.Sscanf(line, "%d %d %d %s", &p.Major, &p.Minor, &p.Blocks, &p.Name)
|
_, err := log.Sscanf(line, "%d %d %d %s", &p.Major, &p.Minor, &p.Blocks, &p.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing line: %q: %w", line, err)
|
return nil, log.Errorf("error parsing line: %q: %w", line, err)
|
||||||
}
|
}
|
||||||
partitions = append(partitions, p)
|
partitions = append(partitions, p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the GPL 3.0
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// An app to submit patches for the 30 GO GUI repos
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.wit.com/gui"
|
||||||
|
"go.wit.com/lib/gadgets"
|
||||||
|
"go.wit.com/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func debug() {
|
||||||
|
for {
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
log.Info("TODO: use this?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGui() {
|
||||||
|
me.myGui = gui.New()
|
||||||
|
me.myGui.InitEmbed(resources)
|
||||||
|
me.myGui.Default()
|
||||||
|
|
||||||
|
mainWindow := gadgets.NewGenericWindow("RiscV Imager", "Show Drives")
|
||||||
|
mainWindow.Custom = func() {
|
||||||
|
log.Warn("Main window close")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
drawWindow(mainWindow)
|
||||||
|
|
||||||
|
// sits here forever
|
||||||
|
debug()
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawWindow(win *gadgets.GenericWindow) {
|
||||||
|
grid := win.Group.RawGrid()
|
||||||
|
|
||||||
|
grid.NewLabel("Drives:")
|
||||||
|
|
||||||
|
me.dd = grid.NewDropdown()
|
||||||
|
me.dd.AddText("/dev/blah")
|
||||||
|
me.dd.Custom = func() {
|
||||||
|
log.Info("todo: changed drive")
|
||||||
|
}
|
||||||
|
grid.NextRow()
|
||||||
|
|
||||||
|
grid.NewButton("doDrives()", func() {
|
||||||
|
doDrives()
|
||||||
|
})
|
||||||
|
|
||||||
|
grid.NewButton("doDrives2()", func() {
|
||||||
|
doDrives2()
|
||||||
|
})
|
||||||
|
|
||||||
|
grid.NewButton("partition drives", func() {
|
||||||
|
log.Info("something")
|
||||||
|
})
|
||||||
|
|
||||||
|
grid.NextRow()
|
||||||
|
|
||||||
|
grid.NewButton("ConfigSave()", func() {
|
||||||
|
log.Info("todo: make code for this")
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
13
getDrives.go
13
getDrives.go
|
@ -1,10 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DevInfo struct {
|
type DevInfo struct {
|
||||||
|
@ -17,7 +18,7 @@ type DevInfo struct {
|
||||||
func doDrives2() {
|
func doDrives2() {
|
||||||
parts, err := parseProcPartitions()
|
parts, err := parseProcPartitions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error reading /proc/partitions: %v\n", err)
|
log.Printf("Error reading /proc/partitions: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +43,14 @@ func doDrives2() {
|
||||||
for _, info := range devs {
|
for _, info := range devs {
|
||||||
devPath := "/dev/" + info.Name
|
devPath := "/dev/" + info.Name
|
||||||
if info.IsRaw {
|
if info.IsRaw {
|
||||||
fmt.Printf("%-12s -> %-8s (raw)\n", devPath, info.Type)
|
s := log.Sprintf("%-12s -> %-8s (raw)", devPath, info.Type)
|
||||||
|
log.Info(s)
|
||||||
|
me.dd.AddText(s)
|
||||||
} else {
|
} else {
|
||||||
if info.Parent != "" {
|
if info.Parent != "" {
|
||||||
fmt.Printf("%-12s -> partition of /dev/%s\n", devPath, info.Parent)
|
log.Printf("%-12s -> partition of /dev/%s\n", devPath, info.Parent)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%-12s -> unknown (no parent found)\n", devPath)
|
log.Printf("%-12s -> unknown (no parent found)\n", devPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
65
main.go
65
main.go
|
@ -5,12 +5,16 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"debug/buildinfo"
|
"debug/buildinfo"
|
||||||
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"plugin"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"go.wit.com/dev/alexflint/arg"
|
"go.wit.com/dev/alexflint/arg"
|
||||||
|
"go.wit.com/gui"
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,9 +22,16 @@ import (
|
||||||
var VERSION string
|
var VERSION string
|
||||||
var BUILDTIME string
|
var BUILDTIME string
|
||||||
|
|
||||||
|
// used for shell auto completion
|
||||||
|
var ARGNAME string = "fixup" // todo: get this from $0 ?
|
||||||
|
|
||||||
|
//go:embed resources/*
|
||||||
|
var resources embed.FS
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
me = new(autoType)
|
me = new(autoType)
|
||||||
me.argpp = arg.MustParse(&argv)
|
gui.InitArg()
|
||||||
|
me.pp = arg.MustParse(&argv)
|
||||||
|
|
||||||
if argv.Bash {
|
if argv.Bash {
|
||||||
argv.doBash()
|
argv.doBash()
|
||||||
|
@ -31,12 +42,21 @@ func main() {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkPlug("../../../toolkits/gocui/gocui.so")
|
||||||
|
// checkPlug("/usr/lib/go-gui-toolkits/gocui.v0.22.46.so")
|
||||||
|
|
||||||
|
/*
|
||||||
if argv.Drives != nil {
|
if argv.Drives != nil {
|
||||||
doDrives()
|
doDrives()
|
||||||
doDrives2()
|
doDrives2()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
listenForBlockEvents()
|
// doDrives()
|
||||||
|
// okExit("everything compiled")
|
||||||
|
|
||||||
|
go listenForBlockEvents()
|
||||||
|
doGui()
|
||||||
okExit("everything compiled")
|
okExit("everything compiled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,26 +91,57 @@ func dumpDebug() {
|
||||||
// Get absolute path of the currently running binary
|
// Get absolute path of the currently running binary
|
||||||
exePath, err := os.Executable()
|
exePath, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error getting executable path:", err)
|
log.Println("Error getting executable path:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve symlinks if necessary
|
// Resolve symlinks if necessary
|
||||||
exePath, err = filepath.EvalSymlinks(exePath)
|
exePath, err = filepath.EvalSymlinks(exePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error resolving symlink:", err)
|
log.Println("Error resolving symlink:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read build info
|
// Read build info
|
||||||
bi, err := buildinfo.ReadFile(exePath)
|
bi, err := buildinfo.ReadFile(exePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error reading build info:", err)
|
log.Println("Error reading build info:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Go Version:", bi.GoVersion)
|
log.Println("Go Version:", bi.GoVersion)
|
||||||
for _, dep := range bi.Deps {
|
for _, dep := range bi.Deps {
|
||||||
fmt.Printf("Dependency: %s %s\n", dep.Path, dep.Version)
|
log.Printf("Dependency: %s %s\n", dep.Path, dep.Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkPlug(pluginPath string) *plugin.Plugin {
|
||||||
|
if err := checkPluginViaSubprocess(pluginPath); err != nil {
|
||||||
|
fmt.Printf("Plugin check failed: %v\n", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := plugin.Open(pluginPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("plugin.Open failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Plugin loaded successfully.")
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkPluginViaSubprocess(path string) error {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get executable path: %w", err)
|
||||||
|
}
|
||||||
|
resolved, err := filepath.EvalSymlinks(exe)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to resolve executable symlink: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(resolved, "--gui-check-plugin", path)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package plugincheck
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/buildinfo"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CheckPluginCompatibility verifies that the plugin .so file was built
|
||||||
|
// with the same Go version and dependency versions as the host binary.
|
||||||
|
func CheckPluginCompatibility(pluginPath string) error {
|
||||||
|
pluginInfo, err := buildinfo.ReadFile(pluginPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read plugin build info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mainInfo, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return errors.New("failed to read main binary build info")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pluginInfo.GoVersion != mainInfo.GoVersion {
|
||||||
|
return fmt.Errorf("Go version mismatch: plugin=%s, host=%s",
|
||||||
|
pluginInfo.GoVersion, mainInfo.GoVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a map of main binary dependencies for quick lookup
|
||||||
|
hostDeps := make(map[string]string)
|
||||||
|
for _, dep := range mainInfo.Deps {
|
||||||
|
hostDeps[dep.Path] = dep.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare plugin dependencies
|
||||||
|
for _, dep := range pluginInfo.Deps {
|
||||||
|
hostVer, ok := hostDeps[dep.Path]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("dependency %s not found in host binary", dep.Path)
|
||||||
|
}
|
||||||
|
if dep.Version != hostVer {
|
||||||
|
return fmt.Errorf("dependency version mismatch for %s: plugin=%s, host=%s",
|
||||||
|
dep.Path, dep.Version, hostVer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
put the GO GUI plugin .so files here
|
Binary file not shown.
|
@ -5,11 +5,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/dev/alexflint/arg"
|
"go.wit.com/dev/alexflint/arg"
|
||||||
|
"go.wit.com/gui"
|
||||||
)
|
)
|
||||||
|
|
||||||
var me *autoType
|
var me *autoType
|
||||||
|
|
||||||
// this app's variables
|
// this app's variables
|
||||||
type autoType struct {
|
type autoType struct {
|
||||||
argpp *arg.Parser // go-arg preprocessor
|
pp *arg.Parser // go-arg preprocessor
|
||||||
|
myGui *gui.Node // the gui toolkit handle
|
||||||
|
dd *gui.Node // the drives dropdown list
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
@ -43,7 +42,7 @@ func listenForBlockEvents() {
|
||||||
|
|
||||||
msg := parseUevent(buf[:n])
|
msg := parseUevent(buf[:n])
|
||||||
if msg["SUBSYSTEM"] == "block" && msg["ACTION"] == "add" {
|
if msg["SUBSYSTEM"] == "block" && msg["ACTION"] == "add" {
|
||||||
fmt.Printf("New block device added: %s\n", msg["DEVNAME"])
|
log.Printf("New block device added: %s\n", msg["DEVNAME"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue